I have made a chat app using this lesson. I have tested it:
Then I closed the app, and opened it some time later. And surprisingly all messages had disappeared:
They appeared back only when I logged out and logged in again.
How to solve that bug?
My code:
MainActivity.java:
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.database.FirebaseListAdapter;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.FirebaseDatabase;
public class MainActivity extends AppCompatActivity {
private static final int SIGN_IN_REQUEST_CODE = 111;
private FirebaseListAdapter<ChatMessage> adapter;
private ListView listView;
private String loggedInUserName = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//find views by Ids
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
final EditText input = (EditText) findViewById(R.id.input);
listView = (ListView) findViewById(R.id.list);
if (FirebaseAuth.getInstance().getCurrentUser() == null) {
// Start sign in/sign up activity
startActivityForResult(AuthUI.getInstance()
.createSignInIntentBuilder()
.build(), SIGN_IN_REQUEST_CODE);
} else {
// User is already signed in, show list of messages
showAllOldMessages();
}
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (input.getText().toString().trim().equals("")) {
Toast.makeText(MainActivity.this, "Please enter some texts!", Toast.LENGTH_SHORT).show();
} else {
FirebaseDatabase.getInstance()
.getReference()
.push()
.setValue(new ChatMessage(input.getText().toString(),
FirebaseAuth.getInstance().getCurrentUser().getDisplayName(),
FirebaseAuth.getInstance().getCurrentUser().getUid())
);
input.setText("");
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_sign_out) {
AuthUI.getInstance().signOut(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(MainActivity.this, "You have logged out!", Toast.LENGTH_SHORT).show();
finish();
}
});
}
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SIGN_IN_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Toast.makeText(this, "Signed in successful!", Toast.LENGTH_LONG).show();
showAllOldMessages();
} else {
Toast.makeText(this, "Sign in failed, please try again later", Toast.LENGTH_LONG).show();
// Close the app
finish();
}
}
}
private void showAllOldMessages() {
loggedInUserName = FirebaseAuth.getInstance().getCurrentUser().getUid();
Log.d("Main", "user id: " + loggedInUserName);
adapter = new MessageAdapter(this, ChatMessage.class, R.layout.item_in_message,
FirebaseDatabase.getInstance().getReference());
listView.setAdapter(adapter);
}
public String getLoggedInUserName() {
return loggedInUserName;
}
}
ChatMessage.java:
public class ChatMessage {
private String messageText;
private String messageUser;
private String messageUserId;
public ChatMessage(String messageText, String messageUser, String messageUserId) {
this.messageText = messageText;
this.messageUser = messageUser;
this.messageUserId = messageUserId;
}
public ChatMessage(){
}
public String getMessageUserId() {
return messageUserId;
}
public void setMessageUserId(String messageUserId) {
this.messageUserId = messageUserId;
}
public String getMessageText() {
return messageText;
}
public void setMessageText(String messageText) {
this.messageText = messageText;
}
public String getMessageUser() {
return messageUser;
}
public void setMessageUser(String messageUser) {
this.messageUser = messageUser;
}
}
ChatAdapter.java:
import android.text.format.DateFormat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.firebase.ui.database.FirebaseListAdapter;
import com.google.firebase.database.DatabaseReference;
public class MessageAdapter extends FirebaseListAdapter<ChatMessage> {
private MainActivity activity;
public MessageAdapter(MainActivity activity, Class<ChatMessage> modelClass, int modelLayout, DatabaseReference ref) {
super(activity, modelClass, modelLayout, ref);
this.activity = activity;
}
#Override
protected void populateView(View v, ChatMessage model, int position) {
TextView messageText = (TextView) v.findViewById(R.id.message_text);
TextView messageUser = (TextView) v.findViewById(R.id.message_user);
messageText.setText(model.getMessageText());
messageUser.setText(model.getMessageUser());
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
ChatMessage chatMessage = getItem(position);
if (chatMessage.getMessageUserId().equals(activity.getLoggedInUserName()))
view = activity.getLayoutInflater().inflate(R.layout.item_out_message, viewGroup, false);
else
view = activity.getLayoutInflater().inflate(R.layout.item_in_message, viewGroup, false);
//generating view
populateView(view, chatMessage, position);
return view;
}
#Override
public int getViewTypeCount() {
// return the total number of view types. this value should never change
// at runtime
return 2;
}
#Override
public int getItemViewType(int position) {
// return a value between 0 and (getViewTypeCount - 1)
return position % 2;
}
}
P.S I have tried to paste code below into onResume method of MainActivity but nothing good is happening.
if (FirebaseAuth.getInstance().getCurrentUser() == null) {
// Start sign in/sign up activity
startActivityForResult(AuthUI.getInstance()
.createSignInIntentBuilder()
.build(), SIGN_IN_REQUEST_CODE);
} else {
// User is already signed in, show list of messages
showAllOldMessages();
}
P.P.S When I try to send new messages in chat, when there is a bug, I see them. But when I log out and login again, these messages are absent.
Check the logs when you close and re-open the app or if you want a tutorial here's one that uses firebase to create a chat application.
Part-1 https://www.youtube.com/watch?v=wVCz1a3ogqk
Part-2 https://www.youtube.com/watch?v=uX6_w6yhj4E
Related
I am currently having a trouble on deleting a specific data from my firebase. So basically I have recyclerview wherein my datas are displayed and I have a button in each data display there and that's EDIT button. Whenever I try to click the EDIT button it should intent me to another activity with the same data displayed in the recyclerview and there's a another button displayed there and that's DELETE button. But whenever I try to click the delete button, it deletes all the data from the child. I only need to DELETE the selected ID/Data that is passing when intent occurs.
Edit.
EditResearch.java
package com.example.citeresearchrepository.AdminPackage;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.citeresearchrepository.Model.ResearchRepository;
import com.example.citeresearchrepository.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.OnProgressListener;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
public class EditResearchActivity extends AppCompatActivity {
EditText editfilehandler_et,editrepo_title,editrepo_description,editrepo_currentdate;
Button editrepo_savebtn;
ImageView backbtn_editresearch;
DatabaseReference databaseReference;
FirebaseDatabase firebaseDatabase;
StorageReference storageReference;
String researchtitle,researchdate,researchname,researchdescription;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_research);
editfilehandler_et = findViewById(R.id.editfilehandler_et);
editrepo_title = findViewById(R.id.editrepo_title);
editrepo_description = findViewById(R.id.editrepo_description);
editrepo_currentdate = findViewById(R.id.editrepo_currentdate);
editrepo_savebtn = findViewById(R.id.editrepo_savebtn);
backbtn_editresearch = findViewById(R.id.backbtn_editresearch);
Intent intent = getIntent();
researchtitle = intent.getStringExtra("researchtitle");
researchdate = intent.getStringExtra("researchdate");
researchname = intent.getStringExtra("researchname");
researchdescription = intent.getStringExtra("researchdescription");
databaseReference = FirebaseDatabase.getInstance().getReference("ResearchRepository");
storageReference = FirebaseStorage.getInstance().getReference();
editfilehandler_et.setText(researchname);
editrepo_title.setText(researchtitle);
editrepo_currentdate.setText(researchdate);
editrepo_description.setText(researchdescription);
editrepo_savebtn.setEnabled(false);
editfilehandler_et.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectPDF();
}
});
/* Update Files */
backbtn_editresearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), AdminResearchRepoActivity.class));
}
});
}
private void selectPDF(){
Intent intent = new Intent();
intent.setType("application/pdf");
intent.setAction(intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "PDF FILE SELECTED"), 12);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==12 && resultCode == RESULT_OK && data!=null && data.getData()!=null){
editrepo_savebtn.setEnabled(true);
editfilehandler_et.setText(data.getDataString().substring(data.getDataString().lastIndexOf("/") + 1));
editrepo_savebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deletePreviousImage();
uploadResearch(data.getData());
}
});
}
}
private void deleteSelectedRow(){
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("ResearchRepository");
databaseReference.removeValue();
}
private void uploadResearch(Uri data) {
final String filecapture = editfilehandler_et.getText().toString();
final String researchtitle = editrepo_title.getText().toString();
final String researchdescription = editrepo_description.getText().toString();
final String researchtimeline = editrepo_currentdate.getText().toString();
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("File Uploading...");
progressDialog.show();
StorageReference reference = storageReference.child("ResearchRepository" +System.currentTimeMillis() + ".pdf");
reference.putFile(data).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
while(!uriTask.isComplete());
Uri uri = uriTask.getResult();
ResearchRepository researchRepository = new ResearchRepository(filecapture,researchtitle,researchdescription,researchtimeline,uri.toString());
databaseReference.child(databaseReference.push().getKey()).setValue(researchRepository);
Toast.makeText(EditResearchActivity.this, "File Uploaded", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
editfilehandler_et.setText("");
editrepo_title.setText("");
editrepo_currentdate.setText("");
editrepo_description.setText("");
startActivity(new Intent(getApplicationContext(), AdminResearchRepoActivity.class));
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(#NonNull UploadTask.TaskSnapshot snapshot) {
double progress = (100*snapshot.getBytesTransferred())/snapshot.getTotalByteCount();
progressDialog.setMessage("File Uploading..."+(int)progress+"%");
}
});
}
private void deletePreviousImage(){
StorageReference reference = FirebaseStorage.getInstance().getReference().child(researchtitle);
reference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(EditResearchActivity.this, "Previous File Deleted", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(EditResearchActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
AdminResearchRepoActivity.java
package com.example.citeresearchrepository.AdminPackage;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.citeresearchrepository.AdminAdapter.AdminRepoAdapter;
import com.example.citeresearchrepository.Model.ResearchRepository;
import com.example.citeresearchrepository.R;
import com.example.citeresearchrepository.ViewHolder.AdminResearchRepositoryViewHolder;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class AdminResearchRepoActivity extends AppCompatActivity {
ImageView adminrepo_backbtn;
RecyclerView reporecycler;
FloatingActionButton addresearch_btn;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
AdminRepoAdapter adminRepoAdapter;
ArrayList<ResearchRepository> researchRepositoryArrayList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_research_repo);
// Buttons
adminrepo_backbtn = findViewById(R.id.backbtn_adminrepo);
addresearch_btn = findViewById(R.id.addresearch_btn);
addresearch_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), AddResearchActivity.class));
}
});
adminrepo_backbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), WelcomeAdminActivity.class));
}
});
// Recycler
reporecycler = findViewById(R.id.reporecycler);
reporecycler.setLayoutManager(new LinearLayoutManager(this));
// Firebase Connection
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference().child("ResearchRepository");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
researchRepositoryArrayList = new ArrayList<ResearchRepository>();
for (DataSnapshot dataSnapshot: snapshot.getChildren()){
ResearchRepository researchRepository = dataSnapshot.getValue(ResearchRepository.class);
researchRepositoryArrayList.add(researchRepository);
}
adminRepoAdapter = new AdminRepoAdapter(AdminResearchRepoActivity.this,researchRepositoryArrayList);
reporecycler.setAdapter(adminRepoAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(AdminResearchRepoActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
AdminRepoAdapter.java
package com.example.citeresearchrepository.AdminAdapter;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.citeresearchrepository.AdminPackage.EditResearchActivity;
import com.example.citeresearchrepository.Model.ResearchRepository;
import com.example.citeresearchrepository.R;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class AdminRepoAdapter extends RecyclerView.Adapter<AdminRepoAdapter.AdminViewHolder> {
Context context;
ArrayList<ResearchRepository> researchRepositories;
public AdminRepoAdapter(Context c, ArrayList<ResearchRepository> repositories){
context = c;
researchRepositories = repositories;
}
#NonNull
#Override
public AdminViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new AdminViewHolder(LayoutInflater.from(context).inflate(R.layout.admineditrepo_row,parent,false));
}
#Override
public void onBindViewHolder(#NonNull AdminViewHolder holder, final int position) {
holder.researchtitle_view.setText(researchRepositories.get(position).getResearchtitle());
holder.researchdate_view.setText(researchRepositories.get(position).getResearchtimeline());
holder.researchname_view.setText(researchRepositories.get(position).getFilecapture());
holder.researchdescription_view.setText(researchRepositories.get(position).getResearchdescription());
holder.btnpdf_edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, EditResearchActivity.class);
intent.putExtra("researchtitle",researchRepositories.get(position).getResearchtitle());
intent.putExtra("researchdate",researchRepositories.get(position).getResearchtimeline());
intent.putExtra("researchname",researchRepositories.get(position).getFilecapture());
intent.putExtra("researchdescription",researchRepositories.get(position).getResearchdescription());
v.getContext().startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return researchRepositories.size();
}
class AdminViewHolder extends RecyclerView.ViewHolder{
public TextView researchtitle_view,researchdate_view,researchname_view,researchdescription_view,researchtitle_url;
public Button btnpdf_edit;
public AdminViewHolder (#NonNull View itemView) {
super(itemView);
researchtitle_view = itemView.findViewById(R.id.researchtitle_view);
researchdate_view = itemView.findViewById(R.id.researchdate_view);
researchname_view = itemView.findViewById(R.id.researchname_view);
researchdescription_view = itemView.findViewById(R.id.researchdescription_view);
researchtitle_url = itemView.findViewById(R.id.researchtitle_view);
btnpdf_edit = itemView.findViewById(R.id.btnpdf_edit);
}
}
}
ResearchRepository.class
package com.example.citeresearchrepository.Model;
public class ResearchRepository {
public String filecapture;
public String researchtitle;
public String researchdescription;
public String researchtimeline;
public String url;
public ResearchRepository() {
}
public ResearchRepository(String filecapture, String researchtitle, String researchdescription, String researchtimeline, String url) {
this.filecapture = filecapture;
this.researchtitle = researchtitle;
this.researchdescription = researchdescription;
this.researchtimeline = researchtimeline;
this.url = url;
}
public String getFilecapture() {
return filecapture;
}
public void setFilecapture(String filecapture) {
this.filecapture = filecapture;
}
public String getResearchtitle() {
return researchtitle;
}
public void setResearchtitle(String researchtitle) {
this.researchtitle = researchtitle;
}
public String getResearchdescription() {
return researchdescription;
}
public void setResearchdescription(String researchdescription) {
this.researchdescription = researchdescription;
}
public String getResearchtimeline() {
return researchtimeline;
}
public void setResearchtimeline(String researchtimeline) {
this.researchtimeline = researchtimeline;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Here's my realtime-database : https://i.stack.imgur.com/lML0i.png
I just wanna delete the red box.
From what I see you are getting an instance to only the ResearchRepository node instead of the specific child node that you want to delete. You need to keep track of the unique IDs you are pushing on to the ResearchRepository node and pass it in the intent as well;
Add the code to pass the unique ID of the ResearchRepository child you want to delete.
Then do this in your new activity where the delete code is present.
String childToDelete; //retrieve the value from the intent
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("ResearchRepository").child(childToDelete);
databaseReference.removeValue();
This should do it if that is your purpose.
Edit 1:-
I got your point. Please follow the approach I will be showing now and it will work for you.
Edit your class as shown below:-
AdminRepoAdapter.java
public class AdminRepoAdapter extends RecyclerView.Adapter<AdminRepoAdapter.AdminViewHolder> {
Context context;
Map<String,ResearchRepository> researchRepositories;
ArrayList<ResearchRepository> researchRepositoriesHolder;
public AdminRepoAdapter(Context c, Map<String,ResearchRepository> repositories){
context = c;
researchRepositories = repositories;
researchRepositoriesHolder = new ArrayList<>(researchRepositories.values());
}
#NonNull
#Override
public AdminViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new AdminViewHolder(LayoutInflater.from(context).inflate(R.layout.admineditrepo_row,parent,false));
}
#Override
public void onBindViewHolder(#NonNull AdminViewHolder holder, final int position) {
holder.researchtitle_view.setText(researchRepositoriesHolder.get(position).getResearchtitle());
holder.researchdate_view.setText(researchRepositoriesHolder.get(position).getResearchtimeline());
holder.researchname_view.setText(researchRepositoriesHOlder.get(position).getFilecapture());
holder.researchdescription_view.setText(researchRepositoriesHolder.get(position).getResearchdescription());
holder.btnpdf_edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Map.Entry<String,ResearchRepository> entry = null; //Just for initialization
for (Map.Entry<String,ResearchRepository> var : researchRepositories.entrySet()) {
if(var.getValue() == researchRepositoriesHolder.get(position)){
entry = var;
break;
}
}
Intent intent = new Intent(context, EditResearchActivity.class);
intent.putExtra("researchtitle",entry.getValue().getResearchtitle());
intent.putExtra("researchdate",entry.getValue().getResearchtimeline());
intent.putExtra("researchname",entry.getValue().getFilecapture());
intent.putExtra("researchdescription",entry.getValue().getResearchdescription());
intent.putExtra("childNodeKey",entry.getKey());
v.getContext().startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return researchRepositoriesHolder.size();
}
class AdminViewHolder extends RecyclerView.ViewHolder{
public TextView researchtitle_view,researchdate_view,researchname_view,researchdescription_view,researchtitle_url;
public Button btnpdf_edit;
public AdminViewHolder (#NonNull View itemView) {
super(itemView);
researchtitle_view = itemView.findViewById(R.id.researchtitle_view);
researchdate_view = itemView.findViewById(R.id.researchdate_view);
researchname_view = itemView.findViewById(R.id.researchname_view);
researchdescription_view = itemView.findViewById(R.id.researchdescription_view);
researchtitle_url = itemView.findViewById(R.id.researchtitle_view);
btnpdf_edit = itemView.findViewById(R.id.btnpdf_edit);
}
}
}
AdminResearchRepoActivity.java
public class AdminResearchRepoActivity extends AppCompatActivity {
ImageView adminrepo_backbtn;
RecyclerView reporecycler;
FloatingActionButton addresearch_btn;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
AdminRepoAdapter adminRepoAdapter;
Map<String, ResearchRepository> researchRepositoryMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_research_repo);
// Buttons
adminrepo_backbtn = findViewById(R.id.backbtn_adminrepo);
addresearch_btn = findViewById(R.id.addresearch_btn);
addresearch_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), AddResearchActivity.class));
}
});
adminrepo_backbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), WelcomeAdminActivity.class));
}
});
// Recycler
reporecycler = findViewById(R.id.reporecycler);
reporecycler.setLayoutManager(new LinearLayoutManager(this));
// Firebase Connection
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference().child("ResearchRepository");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
researchRepositoryMap = (Map)snapshot.getValue()
adminRepoAdapter = new AdminRepoAdapter(AdminResearchRepoActivity.this,researchRepositoryMap);
reporecycler.setAdapter(adminRepoAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(AdminResearchRepoActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
In this way when you pass a Intent from your AdminRepoAdapter to EditResearchActivity you will have the key stored as 'childNodeKey' in your intent.
You can then follow the procedure I mentioned before the edit to delete using the key you got from here.
I'm trying to add firebase auth and firebase database for a simple login/register form but got a crash because User currentUser = documentSnapshot.toObject(User.class); return a null object and I don't understand why.
Here's my code
ProfileActivity :
package fr.tom_d.growthwatcher;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentSnapshot;
import fr.tom_d.growthwatcher.api.UserHelper;
import fr.tom_d.growthwatcher.models.User;
public class ProfilActivity extends BaseActivity {
private static final int UPDATE_USERNAME = 30;
private FirebaseAuth mAuth;
private TextView mUsername;
private EditText mNewUsername;
private ProgressBar mProgressBar;
private Button mButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAuth = FirebaseAuth.getInstance();
setContentView(R.layout.activity_profil);
mUsername = findViewById(R.id.profile_tv_username);
mNewUsername = findViewById(R.id.profile_et_username);
mProgressBar = findViewById(R.id.profile_progressbar);
mButton = findViewById(R.id.profile_change_username_btn);
this.updateUIWhenCreating();
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateUsernameInFirebase();
}
});
}
private void updateUIWhenCreating(){
if (this.getCurrentUser() != null){
//Get email & username from Firebase
String username = TextUtils.isEmpty(this.getCurrentUser().getDisplayName()) ? getString(R.string.info_no_username_found) : this.getCurrentUser().getDisplayName();
//Update views with data
this.mUsername.setText(username);
}
UserHelper.getUser(this.getCurrentUser().getUid()).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
User currentUser = documentSnapshot.toObject(User.class);
String username = TextUtils.isEmpty(currentUser.getUsername()) ? getString(R.string.info_no_username_found) : currentUser.getUsername();
mNewUsername.setText(username);
}
});
}
private void updateUsernameInFirebase(){
String username = this.mNewUsername.getText().toString();
if (this.getCurrentUser() != null){
if (!username.isEmpty() && !username.equals(getString(R.string.info_no_username_found))){
UserHelper.updateUsername(username, this.getCurrentUser().getUid()).addOnFailureListener(this.onFailureListener()).addOnSuccessListener(this.updateUIAfterRESTRequestsCompleted(UPDATE_USERNAME));
}
}
}
private OnSuccessListener<Void> updateUIAfterRESTRequestsCompleted(final int origin){
return new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
switch (origin){
// 8 - Hiding Progress bar after request completed
case UPDATE_USERNAME:
mProgressBar.setVisibility(View.INVISIBLE);
break;
}
}
};
}
}
User :
package fr.tom_d.growthwatcher.models;
import android.support.annotation.Nullable;
public class User {
private String mUid;
#Nullable
private String mUsername;
public User() { }
public User(String uid, String username) {
mUid = uid;
mUsername = username;
}
// --- GETTERS ---
public String getUid() { return mUid; }
public String getUsername() { return mUsername; }
// --- SETTERS ---
public void setUsername(String username) { this.mUsername = username; }
public void setUid(String uid) { this.mUid = uid; }
}
UserHelper :
package fr.tom_d.growthwatcher.api;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import fr.tom_d.growthwatcher.models.User;
public class UserHelper {
private static final String COLLECTION_NAME = "users";
// --- COLLECTION REFERENCE ---
public static CollectionReference getUsersCollection() {
return FirebaseFirestore.getInstance().collection(COLLECTION_NAME);
}
// --- CREATE ---
public static Task<Void> createUser(String uid, String username) {
User userToCreate = new User(uid, username);
return UserHelper.getUsersCollection().document(uid).set(userToCreate);
}
// --- GET ---
public static Task<DocumentSnapshot> getUser(String uid) {
return UserHelper.getUsersCollection().document(uid).get();
}
// --- UPDATE ---
public static Task<Void> updateUsername(String username, String uid) {
return UserHelper.getUsersCollection().document(uid).update("username", username);
}
// --- DELETE ---
public static Task<Void> deleteUser(String uid) {
return UserHelper.getUsersCollection().document(uid).delete();
}
}
I also noticed that my database Firebase was empty while a user must be created when I register with Displayname as his email address if he logs in via google, otherwise the nickname he indicates in an EditText. Then I run my main activity which is supposed to create a user in the database ....
The code of my mainActivity:
package fr.tom_d.growthwatcher;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.support.design.widget.Snackbar;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import fr.tom_d.growthwatcher.api.UserHelper;
public class MainActivity extends BaseActivity {
private final static int RC_SIGN_IN = 100;
private FirebaseAuth mAuth;
private TextView mMail, mId;
private EditText mPlantDate, mRelDate, mTempRel;
private Button mPlantDateBtn, mTempRelBtn, mProfilBtn;
private GraphView mGraph;
private DataPoint[] mDataPoint;
#Override
protected void onCreate(Bundle savedInstanceState) {
mAuth = FirebaseAuth.getInstance();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMail = findViewById(R.id.main_mail);
mId = findViewById(R.id.main_id);
//mGraph = findViewById(R.id.main_graph);
mPlantDate = findViewById(R.id.main_et_date_plant);
mPlantDateBtn = findViewById(R.id.main_ok_plant_btn);
mRelDate = findViewById(R.id.main_et_date_rel);
mTempRel = findViewById(R.id.main_et_temp);
mTempRelBtn = findViewById(R.id.main_ok_temp_btn);
mProfilBtn = findViewById(R.id.main_profil_btn);
//LineGraphSeries<DataPoint> series = new LineGraphSeries<>(mDataPoint);
mPlantDateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
mProfilBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent profileActivity = new Intent(MainActivity.this, ProfilActivity.class);
startActivity(profileActivity);
}
});
}
#Override
public void onStart() {
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
String vEmail = currentUser.getEmail();
String vId = currentUser.getProviderId();
mMail.setText(vEmail);
mId.setText(vId);
}
private void createUserInFirestore(){
if (this.getCurrentUser() != null){
String urlPicture = (this.getCurrentUser().getPhotoUrl() != null) ? this.getCurrentUser().getPhotoUrl().toString() : null;
String username = this.getCurrentUser().getDisplayName();
String uid = this.getCurrentUser().getUid();
UserHelper.createUser(uid, username).addOnFailureListener(this.onFailureListener());
}
}
private void handleResponseAfterSignIn(int requestCode, int resultCode, Intent data){
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
this.createUserInFirestore();
} else {
Toast.makeText(MainActivity.this, "ERREUR CREATION USER FIREBASE",
Toast.LENGTH_SHORT).show();
}
}
}
}
RegisterActivity :
package fr.tom_d.growthwatcher;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.auth.UserProfileChangeRequest;
import fr.tom_d.growthwatcher.api.UserHelper;
public class RegisterActivity extends BaseActivity {
private final static String TAG = "RegisterActivity";
private final static int RC_SIGN_IN = 100;
private FirebaseAuth mAuth;
private Button mStartButton;
private TextView mAppText;
private EditText mPseudo, mMail, mPassword;
private boolean isPseudoOk, isPasswordOk, isMailOk;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAuth = FirebaseAuth.getInstance();
setContentView(R.layout.activity_register);
isMailOk = false;
isPasswordOk = false;
isPseudoOk = false;
mAppText = findViewById(R.id.register_app_text);
mPseudo = findViewById(R.id.register_et_pseudo);
mPassword = findViewById(R.id.register_et_password);
mMail = findViewById(R.id.register_et_email);
mStartButton = findViewById(R.id.register_start_button);
mPseudo.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString().length() >=3){
isPseudoOk=true;
}
if (isPseudoOk && isPasswordOk && isMailOk){
mStartButton.setEnabled(true);
}
else mStartButton.setEnabled(false);
}
#Override
public void afterTextChanged(Editable s) {
}
});
mPassword.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().length() >= 5){
isPasswordOk = true;
}
else isPasswordOk = false;
if (isPseudoOk && isPasswordOk && isMailOk){
mStartButton.setEnabled(true);
}
else mStartButton.setEnabled(false);
}
#Override
public void afterTextChanged(Editable s) {
}
});
mMail.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().length() >= 5){
isMailOk = true;
}
else isMailOk = false;
if (isPseudoOk && isPasswordOk && isMailOk){
mStartButton.setEnabled(true);
}
else mStartButton.setEnabled(false);
}
#Override
public void afterTextChanged(Editable s) {
}
});
mStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mAuth.createUserWithEmailAndPassword(mMail.getText().toString(), mPassword.getText().toString())
.addOnCompleteListener(RegisterActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "createUserWithEmail:success");
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(mPseudo.getText().toString()).build();
getCurrentUser().updateProfile(profileUpdates);
createUserInFirestore();
Intent mainActivity = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(mainActivity);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(RegisterActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
protected void onStart () {
super.onStart();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
Intent mainActivity = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(mainActivity);
}
else {
// No user is signed in
}
}
}
According to the API documentation for toObject(), it will return null if the document doesn't exist. You should first check to see if it exists using exists().
I'm working with Firebase data and RecyclerView Adapter.
The scenario is when user click the list, the initial status was UNREAD will be change to READ so the TypeFace should be change from BOLD to NORMAL.
My current back-end process to change the status from UNREAD to READ is working and updated to Firebase, however the interface of my specific RecyclerView item does not change from BOLD to NORMAL.
What I thought is no need to recall back the Firebase data in order to read the status but the interface should change based on user click.
Anyone can help me?
NotificationActivity.java:
package com.myapp.activity.notification;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.material.nereeducation.R;
import com.material.nereeducation.adapter.AdapterNotification;
import com.material.nereeducation.model.Notification;
import com.material.nereeducation.utils.Tools;
import com.material.nereeducation.widget.LineItemDecoration;
import java.util.ArrayList;
import java.util.List;
public class NotificationActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private AdapterNotification mAdapter;
private ActionModeCallback actionModeCallback;
private ActionMode actionMode;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
initToolbar();
initComponent();
Tools.setSystemBarColor(this, R.color.black);
}
private void initToolbar() {
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Notifications");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private List<Notification> items = new ArrayList<>();
private LinearLayout messageEmptyList;
private void initComponent() {
messageEmptyList = findViewById(R.id.messageEmptyList);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new LineItemDecoration(this, LinearLayout.VERTICAL));
recyclerView.setHasFixedSize(true);
//set data and list adapter
mAdapter = new AdapterNotification(this, items);
recyclerView.setAdapter(mAdapter);
mAdapter.setOnClickListener(new AdapterNotification.OnClickListener() {
#Override
public void onItemClick(View view, Notification obj, int pos) {
if (mAdapter.getSelectedItemCount() > 0) {
enableActionMode(pos);
} else {
// read the inbox which removes bold from the row
Notification notification = mAdapter.getItem(pos);
Toast.makeText(getApplicationContext(), "Read: " + notification.sender_id, Toast.LENGTH_SHORT).show();
updateStatus(notification.notificationId,"read",pos);
}
}
#Override
public void onItemLongClick(View view, Notification obj, int pos) {
enableActionMode(pos);
}
});
actionModeCallback = new ActionModeCallback();
getNotificationData();
}
private void getNotificationData()
{
items.clear();
GsonBuilder builder = new GsonBuilder();
final Gson gson = builder.create();
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
String uuid = firebaseAuth.getUid();
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = firebaseDatabase.getReference();
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.getValue() != null)
{
for(DataSnapshot snapshot: dataSnapshot.getChildren())
{
String dataReceived = gson.toJson(snapshot.getValue());
Notification notificationItems = gson.fromJson(dataReceived, Notification.class);
items.add(notificationItems);
}
mAdapter.notifyDataSetChanged();
}else
{
messageEmptyList.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void updateStatus(final String notificationId, String status, final int position) {
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
String uuid = firebaseAuth.getUid();
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = firebaseDatabase.getReference();
databaseReference.child("notifications/"+uuid+"/data_notification").child(notificationId).child("status").setValue(status
).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
mAdapter.notifyItemChanged(position); //Problem here - how to update text from BOLD to NORMAL for this item?
}
});
}
private void enableActionMode(int position) {
if (actionMode == null) {
actionMode = startSupportActionMode(actionModeCallback);
}
toggleSelection(position);
}
private void toggleSelection(int position) {
mAdapter.toggleSelection(position);
int count = mAdapter.getSelectedItemCount();
if (count == 0) {
actionMode.finish();
} else {
actionMode.setTitle(String.valueOf(count));
actionMode.invalidate();
}
}
private class ActionModeCallback implements ActionMode.Callback {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_delete, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_delete) {
deleteInboxes();
mode.finish();
return true;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mAdapter.clearSelections();
actionMode = null;
}
}
private void deleteInboxes() {
List<Integer> selectedItemPositions = mAdapter.getSelectedItems();
for (int i = selectedItemPositions.size() - 1; i >= 0; i--) {
mAdapter.removeData(selectedItemPositions.get(i));
}
mAdapter.notifyDataSetChanged();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
} else {
Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
}
AdapterNotification.java:
package com.myapp.adapter;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateUtils;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.material.nereeducation.R;
import com.material.nereeducation.helper.AlphabetColor;
import com.material.nereeducation.model.Notification;
import com.material.nereeducation.utils.Tools;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class AdapterNotification extends RecyclerView.Adapter<AdapterNotification.ViewHolder> {
private Context ctx;
private List<Notification> items;
private OnClickListener onClickListener = null;
private SparseBooleanArray selected_items;
private int current_selected_idx = -1;
private AlphabetColor alphabetColor;
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView from, title, message, date, image_letter;
public ImageView image;
public RelativeLayout lyt_checked, lyt_image;
public View lyt_parent;
public ViewHolder(View view) {
super(view);
from = view.findViewById(R.id.from);
title = view.findViewById(R.id.title);
message = view.findViewById(R.id.message);
date = view.findViewById(R.id.date);
image_letter = view.findViewById(R.id.image_letter);
image = view.findViewById(R.id.image);
lyt_checked = view.findViewById(R.id.lyt_checked);
lyt_image = view.findViewById(R.id.lyt_image);
lyt_parent = view.findViewById(R.id.lyt_parent);
}
}
public AdapterNotification(Context mContext, List<Notification> items) {
this.ctx = mContext;
this.items = items;
selected_items = new SparseBooleanArray();
alphabetColor = new AlphabetColor(mContext);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_notification, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Notification notification = items.get(position);
// displaying text view data
System.out.println("sender type:"+notification.sender_type);
Character firstLetter;
if(notification.sender_type.equals("1")) //Admin
{
String admin = ctx.getString(R.string.admin_name);
holder.from.setText(admin);
firstLetter = admin.substring(0, 1).charAt(0);
holder.image_letter.setText(String.valueOf(firstLetter));
}else
{
holder.from.setText(notification.senderName);
firstLetter = notification.senderName.substring(0, 1).charAt(0);
holder.image_letter.setText(String.valueOf(firstLetter));
}
if(notification.status.equals("unread"))
{
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}
holder.title.setText(notification.title);
holder.message.setText(notification.message);
holder.date.setText(getDate(Long.parseLong(notification.date)));
holder.lyt_parent.setActivated(selected_items.get(position, false));
holder.lyt_parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (onClickListener == null) return;
onClickListener.onItemClick(v, notification, position);
}
});
holder.lyt_parent.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (onClickListener == null) return false;
onClickListener.onItemLongClick(v, notification, position);
return true;
}
});
toggleCheckedIcon(holder, position);
displayImage(holder, notification, firstLetter);
}
private void displayImage(ViewHolder holder, Notification notification, Character firstLetter) {
if (notification.image != null) {
Tools.displayImageRound(ctx, holder.image, notification.image);
holder.image.setColorFilter(null);
holder.image_letter.setVisibility(View.GONE);
} else {
holder.image.setImageResource(R.drawable.shape_circle);
holder.image.setColorFilter(alphabetColor.getColorByAlphabet(firstLetter), PorterDuff.Mode.MULTIPLY);
holder.image_letter.setVisibility(View.VISIBLE);
}
}
private String getDate(long time) {
Date date = new Date();
long currentTime = date.getTime();
String result = (String) DateUtils.getRelativeTimeSpanString(time, currentTime, 0);
return result;
}
private void toggleCheckedIcon(ViewHolder holder, int position) {
if (selected_items.get(position, false)) {
holder.lyt_image.setVisibility(View.GONE);
holder.lyt_checked.setVisibility(View.VISIBLE);
if (current_selected_idx == position) resetCurrentIndex();
} else {
holder.lyt_checked.setVisibility(View.GONE);
holder.lyt_image.setVisibility(View.VISIBLE);
if (current_selected_idx == position) resetCurrentIndex();
}
}
public Notification getItem(int position) {
return items.get(position);
}
#Override
public int getItemCount() {
return items.size();
}
public void toggleSelection(int pos) {
current_selected_idx = pos;
if (selected_items.get(pos, false)) {
selected_items.delete(pos);
} else {
selected_items.put(pos, true);
}
notifyItemChanged(pos);
}
public void clearSelections() {
selected_items.clear();
notifyDataSetChanged();
}
public int getSelectedItemCount() {
return selected_items.size();
}
public List<Integer> getSelectedItems() {
List<Integer> items = new ArrayList<>(selected_items.size());
for (int i = 0; i < selected_items.size(); i++) {
items.add(selected_items.keyAt(i));
}
return items;
}
public void removeData(int position) {
items.remove(position);
resetCurrentIndex();
}
private void resetCurrentIndex() {
current_selected_idx = -1;
}
public interface OnClickListener {
void onItemClick(View view, Notification obj, int pos);
void onItemLongClick(View view, Notification obj, int pos);
}
}
You need to handle ELSE too for this condition
if(notification.status.equals("unread")){
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}else{
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
}
if you want to set textview different typeface or color in adapter you need to check for every position so in your case you only setting typeface bold for textview you have to set typeface again normal for default textview typeface.
Set your typeface Normal also in adapter.
set text default typeface Normal for textview like below.
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
and then check item status for unread
if(notification.status.equals("unread")){
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}
So I guess your problem is that the state (read/unread) is applied on the database, but not reflected on the recycler view.
If this is the problem it is mainly because, you didnt handle the data change method of your list (and update it with the new values).
You are currently using this to get data:
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {.....
This won't help you to control the item changed too.
Possible solution
A way solve it is to use (FirebaseUI) database instead of custom adapter.
FirebaseUI will listen to changes and update the list.
EDIT 2
use ChildEventListener instead of Listener For Single Value event
instead of this:
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {.....
use this:
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot) {.....
//add items to list (like you did)
#Override
public void onChildChanged(DataSnapshot dataSnapshot) {.....
//set the items again to the list (update them here) and notify
//data set changed (so values update in your list).
I believe you should set the font like this:
if ("unread".equals(notification.status)) {
holder.from.setTypeface(null, Typeface.BOLD);
holder.title.setTypeface(null, Typeface.BOLD);
} else {
holder.from.setTypeface(null, Typeface.NORMAL);
holder.title.setTypeface(null, Typeface.NORMAL);
}
The view is being reused by RecyclerView so once you set font to bold you need to set it back to normal next time it will be used.
Before starting explaining my problem, i'll show you the full image of my error.
I did my best to find the solution and the reason why this error would happen.
I found a few sources such as this or this.
I'm afraid you guys would think that my question is the same as those questions, but I think that there are some differences, so i really hope you guys read my question.
First, I have followed the official chat app tutorial by Google. (this)
and I just copied the source codes, but the error occured on chapter 8(Send Message). And there were no problems when i send the message just with texts, but problem occured when i send the message with image file from my local storage. And i just found the source that says 'In the google firebase this type of StorageException are commonly caused because of wrong StorageReference reference.', so I looked my source codes about StorageReference. But i couldn't understand that answer and I couldn't find any problems.
Second, I showed you more detail about the error message and i'll show you my full source code of MainActivity.
package com.google.firebase.codelab.friendlychat;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Layout;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.firebase.ui.database.SnapshotParser;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.appinvite.AppInvite;
import com.google.android.gms.appinvite.AppInviteInvitation;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.crash.FirebaseCrash;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import com.google.firebase.appindexing.Action;
import com.google.firebase.appindexing.FirebaseAppIndex;
import com.google.firebase.appindexing.FirebaseUserActions;
import com.google.firebase.appindexing.Indexable;
import com.google.firebase.appindexing.builders.Indexables;
import com.google.firebase.appindexing.builders.PersonBuilder;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.util.HashMap;
import java.util.Map;
import de.hdodenhof.circleimageview.CircleImageView;
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.OnConnectionFailedListener {
public static class MessageViewHolder extends RecyclerView.ViewHolder {
TextView messageTextView;
ImageView messageImageView;
TextView messengerTextView;
CircleImageView messengerImageView;
public MessageViewHolder(View v) {
super(v);
messageTextView = (TextView) itemView.findViewById(R.id.messageTextView);
messageImageView = (ImageView) itemView.findViewById(R.id.messageImageView);
messengerTextView = (TextView) itemView.findViewById(R.id.messengerTextView);
messengerImageView = (CircleImageView) itemView.findViewById(R.id.messengerImageView);
}
public void bind(FriendlyMessage friendlyMessage){
messageTextView.setText(friendlyMessage.getText());
messageTextView.setVisibility(View.VISIBLE);
messageImageView.setVisibility(View.GONE);
}
}
private static final String TAG = "MainActivity";
public static final String MESSAGES_CHILD = "messages";
private static final int REQUEST_INVITE = 1;
private static final int REQUEST_IMAGE = 2;
private static final String LOADING_IMAGE_URL = "https://www.google.com/images/spin-32.gif";
public static final int DEFAULT_MSG_LENGTH_LIMIT = 10;
public static final String ANONYMOUS = "anonymous";
private static final String MESSAGE_SENT_EVENT = "message_sent";
private String mUsername;
private String mPhotoUrl;
private SharedPreferences mSharedPreferences;
private GoogleApiClient mGoogleApiClient;
private static final String MESSAGE_URL = "http://friendlychat.firebase.google.com/message/";
private Button mSendButton;
private RecyclerView mMessageRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private ProgressBar mProgressBar;
private EditText mMessageEditText;
private ImageView mAddMessageImageView;
// Firebase instance variables
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder> mFirebaseAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Set default username is anonymous.
mUsername = ANONYMOUS;
// Initialize Firebase Auth
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getCurrentUser();
if(mFirebaseUser == null){
// Not signed in, launch the Sign In activity
startActivity(new Intent(this, SignInActivity.class));
finish();
return;
}
else {
mUsername = mFirebaseUser.getDisplayName();
if(mFirebaseUser.getPhotoUrl() != null){
mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
}
}
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
.build();
// Initialize ProgressBar and RecyclerView.
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mMessageRecyclerView = (RecyclerView) findViewById(R.id.messageRecyclerView);
mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.setStackFromEnd(true);
// mLinearLayoutManager.setReverseLayout(true);
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
mMessageEditText = (EditText) findViewById(R.id.messageEditText);
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mSharedPreferences
.getInt(CodelabPreferences.FRIENDLY_MSG_LENGTH, DEFAULT_MSG_LENGTH_LIMIT))});
mMessageEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
mSendButton = (Button) findViewById(R.id.sendButton);
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Send messages on click.
FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString(),
mUsername,
mPhotoUrl,
null);
mFirebaseDatabaseReference.child(MESSAGES_CHILD)
.push().setValue(friendlyMessage);
mMessageEditText.setText("");
}
});
mAddMessageImageView = (ImageView) findViewById(R.id.addMessageImageView);
mAddMessageImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Select image for image message on click.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
}
});
// New child entries
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
SnapshotParser<FriendlyMessage> parser = new SnapshotParser<FriendlyMessage>() {
#Override
public FriendlyMessage parseSnapshot(DataSnapshot dataSnapshot) {
FriendlyMessage friendlyMessage = dataSnapshot.getValue(FriendlyMessage.class);
if(friendlyMessage != null){
friendlyMessage.setId(dataSnapshot.getKey());
}
return friendlyMessage;
}
};
DatabaseReference messageRef = mFirebaseDatabaseReference.child(MESSAGES_CHILD);
FirebaseRecyclerOptions<FriendlyMessage> options =
new FirebaseRecyclerOptions.Builder<FriendlyMessage>()
.setQuery(messageRef, parser)
.build();
mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>(options) {
#Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new MessageViewHolder(inflater.inflate(R.layout.item_message, parent, false));
}
#Override
protected void onBindViewHolder(final MessageViewHolder holder, int position, FriendlyMessage friendlyMessage) {
mProgressBar.setVisibility(View.INVISIBLE);
if(friendlyMessage.getText() != null){
holder.bind(friendlyMessage);
}
else {
String imageUrl = friendlyMessage.getImageUrl();
if(imageUrl.startsWith("gs://")) {
StorageReference storageReference = FirebaseStorage.getInstance()
.getReferenceFromUrl(imageUrl);
storageReference.getDownloadUrl().addOnCompleteListener(
new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if(task.isSuccessful()){
String downloadUrl= task.getResult().toString();
Glide.with(holder.messageImageView.getContext())
.load(downloadUrl)
.into(holder.messageImageView);
}
else {
Log.w(TAG, "Getting download url was not seccessful.",
task.getException());
}
}
}
);
}
else {
Glide.with(holder.messageImageView.getContext())
.load(friendlyMessage.getImageUrl())
.into(holder.messageImageView);
}
holder.messageImageView.setVisibility(ImageView.VISIBLE);
holder.messageTextView.setVisibility(TextView.GONE);
}
holder.messengerTextView.setText(friendlyMessage.getName());
if(friendlyMessage.getPhotoUrl() == null){
holder.messengerImageView.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,
R.drawable.ic_account_circle_black_36dp));
}
else {
Glide.with(MainActivity.this)
.load(friendlyMessage.getPhotoUrl())
.into(holder.messengerImageView);
}
}
};
mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosotion =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
if(lastVisiblePosotion == -1 ||
(positionStart >= (friendlyMessageCount - 1) && lastVisiblePosotion == (positionStart - 1))){
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});
mMessageRecyclerView.setAdapter(mFirebaseAdapter);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode);
if (requestCode == REQUEST_IMAGE) {
if (resultCode == RESULT_OK) {
if (data != null) {
final Uri uri = data.getData();
Log.d(TAG, "Uri: " + uri.toString());
FriendlyMessage tempMessage = new FriendlyMessage(null, mUsername, mPhotoUrl,
LOADING_IMAGE_URL);
mFirebaseDatabaseReference.child(MESSAGES_CHILD).push()
.setValue(tempMessage, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError,
DatabaseReference databaseReference) {
if (databaseError == null) {
String key = databaseReference.getKey();
StorageReference storageReference =
FirebaseStorage.getInstance()
.getReference(mFirebaseUser.getUid())
.child(key)
.child( uri.getLastPathSegment());
putImageInStorage(storageReference, uri, key);
} else {
Log.w(TAG, "Unable to write message to database.",
databaseError.toException());
}
}
});
}
}
}
}
private void putImageInStorage(StorageReference storageReference, Uri uri, final String key) {
storageReference.putFile(uri).addOnCompleteListener(MainActivity.this,
new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
FriendlyMessage friendlyMessage =
new FriendlyMessage(null, mUsername, mPhotoUrl,
task.getResult().getMetadata().getDownloadUrl()
.toString());
mFirebaseDatabaseReference.child(MESSAGES_CHILD).child(key)
.setValue(friendlyMessage);
} else {
Log.w(TAG, "Image upload task was not successful.",
task.getException());
}
}
});
}
#Override
public void onStart() {
super.onStart();
// Check if user is signed in.
// TODO: Add code to check if user is signed in.
}
#Override
public void onPause() {
mFirebaseAdapter.stopListening();
super.onPause();
}
#Override
public void onResume() {
super.onResume();
mFirebaseAdapter.startListening();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.sign_out_menu:
mFirebaseAuth.signOut();
Auth.GoogleSignInApi.signOut(mGoogleApiClient);
mUsername = ANONYMOUS;
startActivity(new Intent(this, SignInActivity.class));
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
// An unresolvable error has occurred and Google APIs (including Sign-In) will not
// be available.
Log.d(TAG, "onConnectionFailed:" + connectionResult);
Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}
}
I think I have no problems with Firebase authentication and the intallation or the version of Google Play Service.
Thank you for reading my question.
this is my first post here, so any guidance at all is appreciated.
I'm having an issue when others download my app. It causes the App to crash on launch. It works perfectly when I install updates and seems to be an issue stemming from users not having a Firebase UID created when first launching.
Here is Main Activity Code:
package com.example.android.cellavino;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.example.android.cellavino.PojoDirectory.UI2.UserDetailsPojo;
import com.example.android.cellavino.UserInterface.WineAdapter;
import com.example.android.cellavino.UserInterface2.WineDetails.CreateNewWine;
import com.example.android.cellavino.UserInterface2.CreateTasting.MyTastings;
import com.example.android.cellavino.UserInterface2.EditProfile.EditProfile;
import com.example.android.cellavino.UserInterface2.JoinTasting.JoinTasting;
import com.example.android.cellavino.UserInterface2.WineDetails.MyWinesList;
import com.example.android.cellavino.Utils.Constants;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import com.firebase.ui.auth.AuthUI;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ServerValue;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.storage.FirebaseStorage;
import java.util.Arrays;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final String LOG_TAG = MainActivity.class.getSimpleName();
public static final String ANONYMOUS = "anonymous";
public static final int RC_SIGN_IN = 1;
public String mUsername;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mWineDatabaseReference;
private DatabaseReference mUserDatabaseReference;
private DatabaseReference mMyWinesReference;
private ChildEventListener mChildEventListener;
private FirebaseRemoteConfig mFirebaseRemoteConfig;
private FirebaseStorage mFirebaseStorage;
private WineAdapter mWineAdapter;
private ListView mWineListView;
private RecyclerView mWineRecyclerView;
private RecyclerView.Adapter mAdapter;
private ProgressBar mProgressBar;
private RecyclerView.LayoutManager mLayoutManager;
private DrawerLayout mNavigationDrawerLayout;
private ActionBarDrawerToggle mActionBarDrawerToggle;
private ListView mWineInformation;
private TextView mWineName;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private ListView mDrawerList;
private String[] mMenuOptions;
private Uri userProfilePic;
private TextView mUsernameTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setContentView(R.layout.my_wines_list);
//setContentView(R.layout.activity_container);
//getSupportFragmentManager().beginTransaction().replace(R.id.container, new MyWinesListFragment()).commit();
//Initialise Firebase
Firebase.setAndroidContext(this);
mUsername = ANONYMOUS;
//mTitle = mDrawerTitle = getTitle();
mFirebaseDatabase = FirebaseDatabase.getInstance();
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseStorage = FirebaseStorage.getInstance();
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
//WineDatabase in Firebase initialisation
mWineDatabaseReference = mFirebaseDatabase.getReference().child("Wine Details");
mUserDatabaseReference = mFirebaseDatabase.getReference().child("Users");
mMyWinesReference = mFirebaseDatabase.getReference().child("Users").child("myWines");
//initialising the views
//ListView mWineListView = (ListView) findViewById(R.id.wineListView);
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
//user is signed in
onSignedInInialise(user.getDisplayName());
} else {
//user is signed out
onSignedOutCleanup();
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setProviders(Arrays.asList(
new AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build()))
.build(),
RC_SIGN_IN);
}
}
};
//add code that will bring up the Add_Wine screen when a user clicks on the floating action button for addwine.
FloatingActionButton addWineFab = (FloatingActionButton) findViewById(R.id.addWineFab);
addWineFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, CreateNewWine.class);
startActivity(intent);
}
});
//initialise view_my_wines button click listener
Button viewMyWinesButton = (Button) findViewById(R.id.view_my_wines);
viewMyWinesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, MyWinesList.class);
startActivity(intent);
}
});
//initialise edit_profile button click listener
Button editProfileButton = (Button) findViewById(R.id.edit_profile);
editProfileButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, EditProfile.class);
startActivity(intent);
}
});
//initialise edit_profile button click listener
Button createTastingButton = (Button) findViewById(R.id.create_tasting);
createTastingButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, MyTastings.class);
startActivity(intent);
}
});
//initialise edit_profile button click listener
Button joinTastingButton = (Button) findViewById(R.id.join_tasting);
joinTastingButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, JoinTasting.class);
startActivity(intent);
}
});
FirebaseUser user = mFirebaseAuth.getCurrentUser();
String userName = user.getDisplayName();
if (user != null) {
TextView mUsernameTextView = (TextView) findViewById(R.id.user_name);
mUsernameTextView.setText(userName);
} else {
TextView mUsernameTextView = (TextView) findViewById(R.id.user_name);
mUsernameTextView.setVisibility(View.GONE);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
FirebaseUser user = mFirebaseAuth.getCurrentUser();
String uid = user.getUid();
String userName = user.getDisplayName();
String userEmail = user.getEmail();
Uri userProfilePic = user.getPhotoUrl();
createUserInFirebaseHelper(uid, userName, userEmail);
Toast.makeText(MainActivity.this, "Hello " + userName + "!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(MainActivity.this, "Sign in cancelled", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void createUserInFirebaseHelper(String uid, String userName, String userEmail) {
final String mUserName = userName;
final String mUserEmail = userEmail;
final Firebase userDetailLocation = new Firebase(Constants.FIREBASE_URL_LOCATION_USERS).child(uid);
//See if there is already a user (for example, if they already logged in with an associated google account
userDetailLocation.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(com.firebase.client.DataSnapshot dataSnapshot) {
// If there is no user, make one
if (dataSnapshot.getValue() == null) {
//Set raw version of date to the ServerValue.TIMESTAMP value and save into dateCreatedMap
HashMap<String, Object> timestampJoined = new HashMap<>();
timestampJoined.put(Constants.FIREBASE_PROPERTY_TIMESTAMP, ServerValue.TIMESTAMP);
UserDetailsPojo newUser = new UserDetailsPojo(mUserName, mUserEmail, timestampJoined);
userDetailLocation.setValue(newUser);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.d(LOG_TAG, getString(R.string.log_error_occurred) + firebaseError.getMessage());
}
});
}
//When the app comes back from background state etc
#Override
protected void onResume() {
super.onResume();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
//When the app goes to background state
#Override
protected void onPause() {
super.onPause();
if (mAuthStateListener != null) {
mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
}
detachDatabaseReadListener();
//mWineAdapter.clear();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_navigation_drawer, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//if (mActionBarDrawerToggle.onOptionsItemSelected(item)) {
// return true;
//}
switch (item.getItemId()) {
case R.id.sign_out_menu:
//sign out
AuthUI.getInstance().signOut(this);
return true;
/*
case R.id.menu_add_wine:
//add wine
Intent intent = new Intent(MainActivity.this, AddWine.class);
startActivity(intent);
return true;
case R.id.view_my_wines:
//view the working wine list Andrews Wines
Intent intent2 = new Intent(MainActivity.this, MyWinesList.class);
startActivity(intent2);
return true;
case R.id.test_option:
//view the test screens for Andrews Wines
Intent intent3 = new Intent(MainActivity.this, Login.class);
startActivity(intent3);
return true;
*/
default:
return super.onOptionsItemSelected(item);
}
}
private void onSignedInInialise(String username) {
mUsername = username;
//attachDatabaseReadListener();
//this code adds a new user name each time it logs in.
//mUserDatabaseReference.push().setValue(username);
}
private void onSignedOutCleanup() {
mUsername = ANONYMOUS;
//mWineAdapter.clear();
detachDatabaseReadListener();
}
/*
private void attachDatabaseReadListener() {
if (mChildEventListener == null) {
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
WineDetails wineDetails = dataSnapshot.getValue(WineDetails.class);
//mWineAdapter.add(wineDetails);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
mWineDatabaseReference.addChildEventListener(mChildEventListener);
}
}
*/
private void detachDatabaseReadListener() {
if (mChildEventListener != null) {
mWineDatabaseReference.removeEventListener(mChildEventListener);
mChildEventListener = null;
}
}
private void initializeScreen(View rootView) {
mWineInformation = (ListView) rootView.findViewById(R.id.wine_list_item_details);
mWineName = (TextView) rootView.findViewById(R.id.wine_name);
}
}
How can I adjust it so it checks to see if a user has a profile and if not directs them to the login page?
Thanks in advance.
I figured it out. I was calling getDisplayName() prior to checking authentication.
Thanks for the pointers in how to post a question. I waited 6 months before posting one as I wasn't really sure how/what to ask. Now I know. :)