I'm building a chat app which have post feature, When I create a post in NewPostActivity, the image and text are uploaded (because I can see them in firebase Database tree) but The problem is nothing is shown in my MainActivity which is supposed to display my posts.
I used Firebase UI for the Rv but I'm not sure is the problem lies in NewPostActivity or the MainActivity.
I tried to run the debugger to see but there is no error or null point exception.
NewPostActivity.java
btnPost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startPosting();
}
});
}
private void startPosting() {
progressDialog=new ProgressDialog(NewPostActivity.this);
progressDialog.setTitle("Uploading Image");
progressDialog.setMessage("Please Wait while we process the image");
progressDialog.setCanceledOnTouchOutside(false);
final String desc_val=mPostDesc.getText().toString().trim();
if(!TextUtils.isEmpty(desc_val) && mImageUri!=null){
progressDialog.show();
String random_name= random();
StorageReference filepath = storageReference.child("Blog_Images").child(random_name);
filepath.putFile(mImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
Task<Uri> uriTask = task.getResult().getStorage().getDownloadUrl();
while (!uriTask.isComplete());
final Uri downloadUrl = uriTask.getResult();
final DatabaseReference newPost = mRootRef.child("Blog").push();
final String user_id= mCurrentUser.getUid();
mRootRef.child("Users").child(user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
newPost.child("desc").setValue(desc_val);
newPost.child("image").setValue(downloadUrl.toString());
newPost.child("user_id").setValue(user_id);
newPost.child("timestamp").setValue(ServerValue.TIMESTAMP);
newPost.child("username").setValue(dataSnapshot.child("name").getValue());
newPost.child("thumb_image").setValue(dataSnapshot.child("thumb_image").getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
progressDialog.dismiss();
startActivity(new Intent(NewPostActivity.this,MainActivity.class));
finish();
}
});
}
}
MainActivity.java
Query conversationQuery = mDatabase.orderByChild("timestamp");
FirebaseRecyclerOptions<Blog> options = new FirebaseRecyclerOptions.Builder<Blog>()
.setQuery(conversationQuery, Blog.class)
.build();
FirebaseRecyclerAdapter<Blog, BlogViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Blog, BlogViewHolder>(options) {
#NonNull
#Override
public BlogViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.post_single_layout, parent, false);
mAuth = FirebaseAuth.getInstance();
return new BlogViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull final BlogViewHolder viewHolder, int position, #NonNull final Blog model) {
viewHolder.setContext(getApplicationContext());
final String list_blog_id = getRef(position).getKey();
viewHolder.setLikeBtns(list_blog_id);
Query lastMessageQuery = mDatabase.child(list_blog_id).limitToLast(1);
lastMessageQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
viewHolder.setDesc(model.getDesc());
viewHolder.setImage(model.getImage());
viewHolder.setUsername(model.getUsername());
viewHolder.setStatus(model.getStatus());
viewHolder.setPostImage(model.getThumb_image());
viewHolder.setTime(model.getTimestamp());
userID = model.getUid();
}
#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) {
}
});
viewHolder.postImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent imageFullScreen = new Intent(getApplicationContext(), PhotoActivity.class);
imageFullScreen.putExtra("uid", list_blog_id);
imageFullScreen.putExtra("from", "RequestsFragment");
startActivity(imageFullScreen);
}
});
viewHolder.mLikeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProcessLike = true;
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (mProcessLike) {
if (dataSnapshot.child(list_blog_id).hasChild(mAuth.getCurrentUser().getUid())) {
mDatabaseLike.child(list_blog_id).child(mAuth.getCurrentUser().getUid()).removeValue();
mProcessLike = false;
} else {
mDatabaseLike.child(list_blog_id).child(mAuth.getCurrentUser().getUid()).setValue("Lliked");
mProcessLike = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
};
mBlogList.setAdapter(firebaseRecyclerAdapter);
}
There is some parts of your code that are not shown, also as I don't see a screenshot of your database I don't know if I will give a correct answer, but obviously you need to start listening to the database before you get the data with firebase UI.
So before this:
mBlogList.setAdapter(firebaseRecyclerAdapter);
Add this:
firebaseRecyclerAdapter.startListening();
Refer to this to know more about how to set your firebase UI.
Related
I am building a chatting app. and in it i have a messaging system powered by firebase. and to load them on the front end I am using recycler view however every time I leave the activity and come back it is still fine but when I add a new message after coming back I duplicates
if that seemed hard to understand here is a video showing what is happening
Recycler View Adapter
public List<Chat> chatList;
public FirebaseAuth mAuth;
public DatabaseReference reference;
public DatabaseReference dbRef;
public String userid;
public MessageAdapter(List<Chat> chat, String userId) {
this.chatList = chat;
this.userid = userId;
}
public class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView senderMessage, ReceiverMessage, sender_image_time, receiver_image_time, sender_name, receiver_name, sender_audio_time, receiver_audio_time;
public ImageView messageSenderPicture,messageReceiverPicture;
public CircleImageView receiver_profile_image, sender_profile_image, sender_audio_image, receiver_audio_image;
public SeekBar sender_audio_bar, receiver_audio_bar;
public ImageButton sender_audio_play, receiver_audio_play, sender_audio_pause, receiver_audio_pause;
public ImageView sender_imageView, receiverImageView;
public ConstraintLayout sender_audio_layout, receiver_audio_layout;
public MediaPlayer mediaPlayer;
public Handler handler = new Handler();
public Runnable runnable;
public MessageViewHolder(#NonNull View itemView) {
super(itemView);
senderMessage = itemView.findViewById(R.id.senderText);
ReceiverMessage = itemView.findViewById(R.id.receiverText);
messageReceiverPicture = itemView.findViewById(R.id.message_receiver_image_view);
messageSenderPicture = itemView.findViewById(R.id.message_sender_image_view);
sender_image_time = itemView.findViewById(R.id.sender_time_image);
receiver_image_time = itemView.findViewById(R.id.receiver_time_image);
receiver_profile_image = itemView.findViewById(R.id.receiver_profile_image);
sender_profile_image = itemView.findViewById(R.id.sender_profile_image);
sender_name = itemView.findViewById(R.id.sender_name);
receiver_name = itemView.findViewById(R.id.receiver_name);
sender_audio_layout = itemView.findViewById(R.id.sender_audio_layout);
receiver_audio_layout = itemView.findViewById(R.id.receiver_audio_layout);
sender_audio_image = itemView.findViewById(R.id.sender_image_audio);
receiver_audio_image = itemView.findViewById(R.id.receiver_image_audio);
sender_audio_bar = itemView.findViewById(R.id.seekBar);
receiver_audio_bar = itemView.findViewById(R.id.receiver_seekBar);
sender_audio_play = itemView.findViewById(R.id.sender_play);
receiver_audio_play = itemView.findViewById(R.id.receiver_play);
sender_audio_time = itemView.findViewById(R.id.sender_audio_time);
receiver_audio_time = itemView.findViewById(R.id.receiver_audio_time);
sender_imageView = itemView.findViewById(R.id.imageView4);
receiverImageView = itemView.findViewById(R.id.receiver_imageView4);
sender_audio_pause = itemView.findViewById(R.id.sender_pause);
receiver_audio_pause = itemView.findViewById(R.id.receiver_pause);
mediaPlayer = new MediaPlayer();
}
}
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_meeage_layout, parent, false);
mAuth = FirebaseAuth.getInstance();
return new MessageViewHolder(view);
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull final MessageViewHolder holder, final int position) {
String messageSenderId = Objects.requireNonNull(mAuth.getCurrentUser()).getUid();
final Chat chat = chatList.get(position);
String fromUserID = chat.getSender();
String userID = chat.getReceiver();
String fromMessageType = chat.getType();
reference = FirebaseDatabase.getInstance().getReference().child("Users").child(fromUserID);
dbRef = FirebaseDatabase.getInstance().getReference().child(userID);
holder.senderMessage.setVisibility(View.GONE);
holder.ReceiverMessage.setVisibility(View.GONE);
holder.messageSenderPicture.setVisibility(View.GONE);
holder.messageReceiverPicture.setVisibility(View.GONE);
holder.receiver_image_time.setVisibility(View.GONE);
holder.sender_image_time.setVisibility(View.GONE);
holder.sender_profile_image.setVisibility(View.GONE);
holder.receiver_profile_image.setVisibility(View.GONE);
holder.sender_name.setVisibility(View.GONE);
holder.receiver_name.setVisibility(View.GONE);
holder.sender_audio_layout.setVisibility(View.GONE);
holder.receiver_audio_layout.setVisibility(View.GONE);
if (fromMessageType.equals("text")) {
if (fromUserID.equals(messageSenderId)) {
holder.senderMessage.setVisibility(View.VISIBLE);
holder.senderMessage.setBackgroundResource(R.drawable.sender_layout);
holder.senderMessage.setText(chat.getMessage() + "\n" + " " + chat.getTime());
} else {
holder.senderMessage.setVisibility(View.INVISIBLE);
holder.ReceiverMessage.setVisibility(View.VISIBLE);
holder.ReceiverMessage.setBackgroundResource(R.drawable.receiver_layout);
holder.ReceiverMessage.setText(chat.getMessage() + "\n" + " " + chat.getTime());
}
}else if (fromMessageType.equals("image")) {
if (fromUserID.equals(messageSenderId)) {
holder.messageSenderPicture.setVisibility(View.VISIBLE);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("Users").child(messageSenderId).child("name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String name = snapshot.getValue().toString();
holder.sender_name.setText(name);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.sender_name.setVisibility(View.VISIBLE);
ref.child("Users").child(messageSenderId).child("image").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String imageUrl = snapshot.getValue().toString();
Picasso.get().load(imageUrl).into(holder.sender_profile_image);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.sender_profile_image.setVisibility(View.VISIBLE);
Picasso.get().load(chat.getMessage()).into(holder.messageSenderPicture);
holder.sender_image_time.setVisibility(View.VISIBLE);
holder.sender_image_time.setText(chat.getTime());
} else {
holder.messageReceiverPicture.setVisibility(View.VISIBLE);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("Users").child(userid).child("name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String name = snapshot.getValue().toString();
holder.receiver_name.setText(name);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.receiver_name.setVisibility(View.VISIBLE);
ref.child("Users").child(userid).child("image").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String imageUrl = snapshot.getValue().toString();
Picasso.get().load(imageUrl).into(holder.receiver_profile_image);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.receiver_profile_image.setVisibility(View.VISIBLE);
Picasso.get().load(chat.getMessage()).into(holder.messageReceiverPicture);
holder.receiver_image_time.setVisibility(View.VISIBLE);
holder.receiver_image_time.setText(chat.getTime());
}
} else if(fromMessageType.equals("audio")) {
if (fromUserID.equals(messageSenderId)) {
holder.sender_audio_layout.setVisibility(View.VISIBLE);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("Users").child(messageSenderId).child("image").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String imageUrl = snapshot.getValue().toString();
Picasso.get().load(imageUrl).into(holder.sender_audio_image);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.sender_audio_time.setText(chat.getTime());
final MediaPlayer mediaPlayer = new MediaPlayer();
holder.sender_audio_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.sender_audio_play.setVisibility(View.INVISIBLE);
holder.sender_audio_pause.setVisibility(View.VISIBLE);
try {
mediaPlayer.setDataSource(chat.getMessage());
mediaPlayer.prepare();
mediaPlayer.start();
holder.sender_audio_bar.setProgress(mediaPlayer.getCurrentPosition());
} catch (IOException e) {
e.printStackTrace();
}
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
holder.sender_audio_play.setVisibility(View.VISIBLE);
holder.sender_audio_pause.setVisibility(View.INVISIBLE);
holder.sender_audio_bar.setProgress(mediaPlayer.getCurrentPosition());
}
});
holder.sender_audio_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.sender_audio_play.setVisibility(View.VISIBLE);
holder.sender_audio_pause.setVisibility(View.INVISIBLE);
mediaPlayer.pause();
mediaPlayer.reset();
holder.sender_audio_bar.setProgress(mediaPlayer.getCurrentPosition());
}
});
} else {
holder.receiver_audio_layout.setVisibility(View.VISIBLE);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("Users").child(userid).child("image").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String imageUrl = snapshot.getValue().toString();
Picasso.get().load(imageUrl).into(holder.receiver_audio_image);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.receiver_audio_time.setText(chat.getTime());
final MediaPlayer mediaPlayer = new MediaPlayer();
holder.receiver_audio_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.receiver_audio_play.setVisibility(View.INVISIBLE);
holder.receiver_audio_pause.setVisibility(View.VISIBLE);
try {
mediaPlayer.setDataSource(chat.getMessage());
mediaPlayer.prepare();
mediaPlayer.start();
holder.receiver_audio_bar.setProgress(mediaPlayer.getCurrentPosition());
} catch (IOException e) {
e.printStackTrace();
}
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
holder.receiver_audio_play.setVisibility(View.VISIBLE);
holder.receiver_audio_pause.setVisibility(View.INVISIBLE);
holder.receiver_audio_bar.setProgress(mediaPlayer.getCurrentPosition());
}
});
holder.receiver_audio_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.receiver_audio_play.setVisibility(View.VISIBLE);
holder.receiver_audio_pause.setVisibility(View.INVISIBLE);
mediaPlayer.pause();
mediaPlayer.reset();
holder.receiver_audio_bar.setProgress(mediaPlayer.getCurrentPosition());
}
});
}
} else {
if (fromUserID.equals(messageSenderId)) {
holder.messageSenderPicture.setVisibility(View.VISIBLE);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("Users").child(messageSenderId).child("image").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String imageUrl = snapshot.getValue().toString();
Picasso.get().load(imageUrl).into(holder.sender_profile_image);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.sender_profile_image.setVisibility(View.VISIBLE);
holder.messageSenderPicture.setBackgroundResource(R.drawable.file);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(chatList.get(position).getMessage()));
holder.itemView.getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(holder.itemView.getContext(), "Your Current Device Doesn't have the application to preview this file", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
});
} else {
holder.messageReceiverPicture.setVisibility(View.VISIBLE);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("Users").child(userid).child("image").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String imageUrl = snapshot.getValue().toString();
Picasso.get().load(imageUrl).into(holder.receiver_profile_image);
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.receiver_profile_image.setVisibility(View.VISIBLE);
holder.messageReceiverPicture.setBackgroundResource(R.drawable.file);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(chatList.get(position).getMessage()));
holder.itemView.getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(holder.itemView.getContext(), "Your Current Device Doesn't have the application to preview this file", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
});
}
}
}
#Override
public int getItemCount() {
return chatList.size();
}
}
My Chat Activity
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#SuppressLint("ShowToast")
#Override
protected void onStart() {
super.onStart();
Toast.makeText(SarimPage.this, fUser.getUid(), Toast.LENGTH_SHORT); // Validate Id
Global global = new Global();
global.updateUserStatus("Active Now");
reference.child("Users").child(Objects.requireNonNull(getIntent().getStringExtra("userID"))).child("userState")
.addValueEventListener(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
String status21 = Objects.requireNonNull(snapshot.child("state").getValue()).toString();
String time = Objects.requireNonNull(snapshot.child("time").getValue()).toString();
if (status21.equals("offline")) {
status2.setVisibility(View.VISIBLE);
userStatus.setText("Last Seen " + time);
}
if(status21.equals("online")) {
status2.setVisibility(View.INVISIBLE);
status.setVisibility(View.VISIBLE);
userStatus.setText(status21);
}
if(status21.equals("Active Now")){
status2.setVisibility(View.INVISIBLE);
status.setVisibility(View.VISIBLE);
userStatus.setText(status21);
}
if(status21.equals("typing...")){
status2.setVisibility(View.INVISIBLE);
status.setVisibility(View.VISIBLE);
userStatus.setText(status21);
}
if (status21.equals("away")) {
status3.setVisibility(View.VISIBLE);
userStatus.setText(status21);
}
} else {}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
reference.child("Messages").addChildEventListener(new ChildEventListener() {
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onChildAdded(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
Chat chats = snapshot.getValue(Chat.class);
assert chats != null;
if(chats.getReceiver().equals(currentUser) && chats.getSender().equals(userID)
|| chats.getReceiver().equals(userID) && chats.getSender().equals(currentUser)) {
chatList.add(chats);
}
messageAdapter.notifyDataSetChanged();
messageList.smoothScrollToPosition(Objects.requireNonNull(messageList.getAdapter()).getItemCount());
}
#Override
public void onChildChanged(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot snapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onUserLeaveHint() {
Global global = new Global();
global.updateUserStatus("offline");
chatList.clear();
super.onUserLeaveHint();
}
#Override
protected void onStop() {
super.onStop();
chatList.clear();
}
#Override
protected void onDestroy() {
super.onDestroy();
chatList.clear();
}
Sorry there is way too much code in this activity so i am only showing methods i think will be usefull such as what i am doing on acitivty start stop or pause.
Chat Model
public class Chat {
private String sender;
private String receiver;
private String message;
private String time;
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Chat() {}
public Chat(String sender, String receiver, String message) {
this.message = message;
this.receiver = receiver;
this.sender = sender;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
(Also when i do this i want all the previous chat history to still be displayed)
I'm not really sure if this is the main source of your problems, but it seems like the ChildEventListener you're adding on Messages reference is being called every time the activity is launched or relaunched. This has the effect of adding multiple listener to the Messages reference (multiple time the lates child added to your RecyclerView), what you should do is to maybe move the
reference.child("Messages").addChildEventListener(new ChildEventListener() {...}
inside onCreate or make sure there is only one ChildEventListener listening to your Messages reference when launching your activity.
Hope this will help, have a good day :)
Get same firebase instance when you reopen app.
FirebaseDatabase database;
//always use this getFirebaseDatabase() method when you need database instance.
public FirebaseDatabase getFirebaseDatabase() {
if(database==null){
database=FirebaseDatabase.getInstance();
}
return database;
}
does anyone here encountered when you are updating a data it duplicates the existing data visually only but when I will back and go to the activity again it shows the real data.
Data 1 and Data 2, when I delete Data 2, it will show Data 1 Data2 and Data 1. However like I said, it is just visual had to go back and go to the activity again to show the current data which is Data 1 only since Data 2 has been deleted. I have tried searching but none of them are related to my problem and I genuinely do not know if this is from the database or the card or in the recyclerview. Any help will be much appreciated.
MainActivity
public class AdminReqFormsActivity extends AppCompatActivity {
RecyclerView adminreqform_recycler;
ImageView adminreqfromfield_backbtn;
DatabaseReference databaseReference;
ArrayList<ResearchReqForm> reqFormArrayList;
AdminRequestFormAdapter adminRequestFormAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_req_forms);
adminreqform_recycler = findViewById(R.id.adminreqform_recycler);
adminreqfromfield_backbtn = findViewById(R.id.adminreqfromfield_backbtn);
databaseReference = FirebaseDatabase.getInstance().getReference("ResearchRequest");
adminreqform_recycler.setLayoutManager(new LinearLayoutManager(this));
reqFormArrayList = new ArrayList<ResearchReqForm>();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
ResearchReqForm researchReqForm = dataSnapshot.getValue(ResearchReqForm.class);
reqFormArrayList.add(researchReqForm);
}
adminRequestFormAdapter = new AdminRequestFormAdapter(AdminReqFormsActivity.this, reqFormArrayList);
adminreqform_recycler.setAdapter(adminRequestFormAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(AdminReqFormsActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
adminreqfromfield_backbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), WelcomeAdminActivity.class));
}
});
}
}
Model
public class ResearchReqForm {
String studentName;
String requestedtitle;
String requestedtags;
String requestMessage;
String requestid;
String requestStatus;
public ResearchReqForm() {
}
public ResearchReqForm(String studentName, String requestedtitle, String requestedtags, String requestMessage, String requestid, String requestStatus) {
this.studentName = studentName;
this.requestedtitle = requestedtitle;
this.requestedtags = requestedtags;
this.requestMessage = requestMessage;
this.requestid = requestid;
this.requestStatus = requestStatus;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getRequestedtitle() {
return requestedtitle;
}
public void setRequestedtitle(String requestedtitle) {
this.requestedtitle = requestedtitle;
}
public String getRequestedtags() {
return requestedtags;
}
public void setRequestedtags(String requestedtags) {
this.requestedtags = requestedtags;
}
public String getRequestMessage() {
return requestMessage;
}
public void setRequestMessage(String requestMessage) {
this.requestMessage = requestMessage;
}
public String getRequestid() {
return requestid;
}
public void setRequestid(String requestid) {
this.requestid = requestid;
}
public String getRequestStatus() {
return requestStatus;
}
public void setRequestStatus(String requestStatus) {
this.requestStatus = requestStatus;
}
}
Adapter
public class AdminRequestFormAdapter extends RecyclerView.Adapter<AdminRequestFormAdapter.AdminRequestFormViewHolder> {
Context context;
ArrayList<ResearchReqForm> requestFormArrayList;
public AdminRequestFormAdapter(Context c, ArrayList<ResearchReqForm> reqFormsList){
context = c;
requestFormArrayList = reqFormsList;
}
#NonNull
#Override
public AdminRequestFormViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new AdminRequestFormAdapter.AdminRequestFormViewHolder(LayoutInflater.from(context).inflate(R.layout.admin_request_list,parent,false));
}
#Override
public void onBindViewHolder(#NonNull AdminRequestFormViewHolder holder, final int position) {
holder.adminsudentname_reqcv.setText(requestFormArrayList.get(position).getStudentName());
holder.adminrelatedtopic_requestcv.setText(requestFormArrayList.get(position).getRequestedtitle());
holder.admintopictags_requestcv.setText(requestFormArrayList.get(position).getRequestedtags());
holder.adminbriefmessage_reqeuestcv.setText(requestFormArrayList.get(position).getRequestMessage());
holder.deleteresearch_request.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Delete Request Research?");
alert.setMessage("Are you sure you want to delete?");
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("ResearchRequest");
final String uniqueKey = requestFormArrayList.get(position).getRequestid();
databaseReference.child(uniqueKey).removeValue();
Toast.makeText(context, "Student's Request has been deleted.", Toast.LENGTH_SHORT).show();
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(context, "Form Closed.", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
alert.show();
}
});
holder.acceptresearch_request.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Test Toast For Accept", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return requestFormArrayList.size();
}
class AdminRequestFormViewHolder extends RecyclerView.ViewHolder{
TextView adminsudentname_reqcv, adminrelatedtopic_requestcv, admintopictags_requestcv, adminbriefmessage_reqeuestcv;
Button deleteresearch_request, acceptresearch_request;
public AdminRequestFormViewHolder(#NonNull View itemView) {
super(itemView);
adminsudentname_reqcv = itemView.findViewById(R.id.adminsudentname_reqcv);
adminrelatedtopic_requestcv =itemView.findViewById(R.id.adminrelatedtopic_requestcv);
admintopictags_requestcv = itemView.findViewById(R.id.admintopictags_requestcv);
adminbriefmessage_reqeuestcv = itemView.findViewById(R.id.adminbriefmessage_reqeuestcv);
deleteresearch_request = itemView.findViewById(R.id.deleteresearch_request);
acceptresearch_request = itemView.findViewById(R.id.acceptresearch_request);
}
}
}
Yes, this is actually quite common and comes from a misunderstanding of how Firebase snapshots work.
Whenever your onDataChange is called it gets a full snapshot of all the data at databaseReference. So even if there's only one change since you rendered the data, you get called with a full snapshot of all data at databaseReference including the change. And since you add all data in snapshot to reqFormArrayList, you end up duplicating it each time onDataChange gets called.
The simplest solution is to clear reqFormArrayList inside onDataChange:
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
reqFormArrayList.clear(); // this is the new line
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
ResearchReqForm researchReqForm = dataSnapshot.getValue(ResearchReqForm.class);
reqFormArrayList.add(researchReqForm);
}
adminRequestFormAdapter = new AdminRequestFormAdapter(AdminReqFormsActivity.this, reqFormArrayList);
adminreqform_recycler.setAdapter(adminRequestFormAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(AdminReqFormsActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
})
i have a button in an activity to send a message by it
the problem is if the person entered the page the button send the message
but if he exit from the page and opened it again .. the button not working
its like became disabled
and the solutions that i used
1 - i disabled the butterknife library and used
setOnClickListener
2 - i added
android:clickable="true"
android:focusable="false"
android:focusableInTouchMode="false"
but it didnt work
and i used the log as a test
.. and its like the button became disabled
although
another page have a similar code
and the button working perfectly in it
and this is the activity xml code
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:windowSoftInputMode="adjustPan"
android:layoutDirection="rtl"
android:textDirection="rtl"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
tools:context=".Activities.SentMessagesActivity">
<include layout="#layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tb_sent_Messages"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="#dimen/dp_0"
app:layout_constraintBottom_toTopOf="#+id/et_sent_messages"
app:layout_constraintTop_toBottomOf="#id/tb_sent_Messages"
android:layout_marginBottom="#dimen/dp_10"
android:id="#+id/srl_sent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="#dimen/dp_0"
android:background="#drawable/new_background"
android:isScrollContainer="false"
android:id="#+id/rv_sent_messages"
android:padding="#dimen/dp_10" />
</android.support.v4.widget.SwipeRefreshLayout>
<Button
android:id="#+id/ib_sent_messages_send"
android:layout_height="#dimen/dp_40"
android:layout_width="#dimen/dp_40"
android:layout_margin="#dimen/dp_10"
android:layout_marginStart="8dp"
android:background="#drawable/sent"
android:clickable="true"
android:focusable="false"
android:focusableInTouchMode="false"
app:layout_constraintStart_toEndOf="#id/et_sent_messages"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<EditText
android:id="#+id/et_sent_messages"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/dp_10"
android:background="#drawable/edittextborders"
android:hint="#string/write_ypur_message"
android:maxHeight="#dimen/dp_70"
android:padding="#dimen/dp_10"
android:onClick="openKeyboard"
app:layout_constraintEnd_toStartOf="#+id/ib_sent_messages_send"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<requestFocus />
</EditText>
and the Java code
public class SentMessagesActivity extends AppCompatActivity {
Button mSend;
#BindView(R.id.tb_sent_Messages)
Toolbar mToolbar;
#BindView(R.id.rv_sent_messages)
RecyclerView mMessagesList;
#BindView(R.id.et_sent_messages)
EditText mMessage;
#BindView(R.id.srl_sent)
SwipeRefreshLayout mRefresh;
TinyDB db;
private FirebaseRecyclerAdapter<Message, MessagesHolder> mAdapter;
private ActionBar mActionBar;
private FirebaseAuth mAuth;
private DatabaseReference mFriendContacts;
private DatabaseReference mMyMessagesRef;
private DatabaseReference mFriendMessagesRef;
private DatabaseReference mFriendRef;
private DatabaseReference mMyRef;
private DatabaseReference mReference;
private int count;
private int mCurrentPage = 1;
private String myImage;
private Dialog mProgressDialoge;
private String myId;
private String friendId = "";
private String Image = "";
private Long State;
private String Name = "";
private TextView mToolTitle ,mToolState;
private TimeAgo timeAgo;
private String myName = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sent_messages);
ButterKnife.bind(this);
mProgressDialoge = new Dialog(SentMessagesActivity.this);
friendId = getIntent().getStringExtra(App_Constants.FRIEND_ID);
mAuth = FirebaseAuth.getInstance();
myId = mAuth.getUid();
db = new TinyDB(this);
mSend = findViewById(R.id.ib_sent_messages_send);
mReference = FirebaseDatabase.getInstance().getReference().child(App_Constants.USERS_CELL).child(myId).child(App_Constants.USER_INFO_CELL);
mReference.keepSynced(true);
mMyMessagesRef = FirebaseDatabase.getInstance().getReference().child(App_Constants.USERS_CELL).child(myId).child(App_Constants.MESSAGES_CELL).child(App_Constants.SENT_CELL).child(friendId);
mMyMessagesRef.keepSynced(true);
mFriendMessagesRef = FirebaseDatabase.getInstance().getReference().child(App_Constants.USERS_CELL).child(friendId).child(App_Constants.MESSAGES_CELL).child(App_Constants.RECEIVED).child(myId);
mFriendMessagesRef.keepSynced(true);
mFriendRef = FirebaseDatabase.getInstance().getReference().child(App_Constants.USERS_CELL).child(friendId).child(App_Constants.USER_INFO_CELL);
mFriendRef.keepSynced(true);
mMyRef = FirebaseDatabase.getInstance().getReference().child(App_Constants.USERS_CELL).child(myId).child(App_Constants.CONTACTS_CELL).child(App_Constants.SENT_CELL);
mMyRef.keepSynced(true);
mFriendContacts = FirebaseDatabase.getInstance().getReference().child(App_Constants.USERS_CELL).child(friendId).child(App_Constants.CONTACTS_CELL).child(App_Constants.RECEIVED);
mFriendContacts.keepSynced(true);
App_Utilities.initializingProgress(mProgressDialoge);
mProgressDialoge.show();
mReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
myImage= dataSnapshot.child(App_Constants.USER_IMAGE_CELL).getValue().toString();
myName = dataSnapshot.child(App_Constants.USER_NAME_CELL).getValue().toString();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mMyMessagesRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
count = (int) dataSnapshot.getChildrenCount();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
setSupportActionBar(mToolbar);
getSupportActionBar().setTitle("");
mActionBar = getSupportActionBar();
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setDisplayShowCustomEnabled(true);
initializingActionBar();
intitializingRecyclerView();
mRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mCurrentPage++;
intitializingRecyclerView();
}
});
refreshingLayout();
mSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String Text = mMessage.getText().toString().trim();
Toast.makeText(SentMessagesActivity.this, "Clicked", Toast.LENGTH_SHORT).show();
if (!TextUtils.isEmpty(Text))
{
message(Text.trim());
}
}
});
}
#Override
protected void onStart() {
super.onStart();
if (mAuth.getCurrentUser() == null)
{
App_Utilities.startEndActivity(SentMessagesActivity.this,StartActivity.class);
mProgressDialoge.dismiss();
}
mAdapter.startListening();
mProgressDialoge.show();
new CountDownTimer(1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
if (count > 15)
{
mMessagesList.scrollToPosition(App_Constants.TOTAL_ITEMS_TO_LOAD - 1);
} else
{
mMessagesList.scrollToPosition(count - 1);
}
mProgressDialoge.hide();
}
}.start();
mFriendMessagesRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if ((boolean)dataSnapshot.child(App_Constants.SEEN).getValue() == false)
{
mFriendMessagesRef.child(dataSnapshot.getKey()).child(App_Constants.SEEN).setValue(true);
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
protected void onPause() {
super.onPause();
db.putBoolean(App_Constants.ISWORKING,false);
}
// public void onClickImage(View view) {
//
//
// }
#Override
protected void onResume() {
super.onResume();
db.putBoolean(App_Constants.ISWORKING,true);
}
private void refreshingLayout()
{
mMyMessagesRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if (count > 15)
{
mMessagesList.scrollToPosition(App_Constants.TOTAL_ITEMS_TO_LOAD - 1);
} else
{
mMessagesList.scrollToPosition(count - 1);
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void message(String Text) {
final HashMap map = new HashMap();
map.put(App_Constants.MESSAGES_CELL,Text);
map.put(App_Constants.FROM,myId);
map.put(App_Constants.SEEN,false);
map.put(App_Constants.TYPE,App_Constants.SENT_CELL);
mMyMessagesRef.push().setValue(map).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful())
{
map.put(App_Constants.TYPE,App_Constants.RECEIVED);
mFriendMessagesRef.push().setValue(map).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful())
{
mMessage.setText("");
if (count > 15)
{
mMessagesList.scrollToPosition((App_Constants.TOTAL_ITEMS_TO_LOAD * mCurrentPage )- 1);
} else
{
mMessagesList.scrollToPosition(count - 1);
}
}
else
{
Toast.makeText(SentMessagesActivity.this, R.string.failed_to_send, Toast.LENGTH_SHORT).show();
}
}
});
}else
{
Toast.makeText(SentMessagesActivity.this, R.string.failed_to_send, Toast.LENGTH_SHORT).show();
}
}
});
}
private void initializingActionBar()
{
LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = mInflater.inflate(R.layout.messages_toolbar,null);
mActionBar.setCustomView(view);
mToolTitle = findViewById(R.id.tv_toolbar_name);
mToolState = findViewById(R.id.tv_toolbar_state);
mFriendRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Name = dataSnapshot.child(App_Constants.USER_NAME_CELL).getValue().toString();
Image = dataSnapshot.child(App_Constants.USER_IMAGE_CELL).getValue().toString();
State = (Long) dataSnapshot.child(App_Constants.ONLINE_CELL).getValue();
mToolTitle.setText(Name);
mToolTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openProfile();
}
});
if (State == App_Constants.ZERO)
{
mToolState.setText(R.string.online);
} else
{
mToolState.setText(TimeAgo.getTimeAgo(State,getApplicationContext()));
}
mProgressDialoge.hide();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void intitializingRecyclerView()
{
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
mMessagesList.setLayoutManager(layoutManager);
mMessagesList.setHasFixedSize(true);
Query mQuery = mMyMessagesRef.limitToLast(mCurrentPage * App_Constants.TOTAL_ITEMS_TO_LOAD);
FirebaseRecyclerOptions mOptions = new FirebaseRecyclerOptions.Builder<Message>()
.setQuery(mQuery,Message.class).build();
mAdapter = new FirebaseRecyclerAdapter<Message, MessagesHolder>(mOptions) {
#Override
protected void onBindViewHolder(#NonNull MessagesHolder holder, int position, #NonNull Message model) {
if (model.getFrom().equals(myId))
{
holder.fillSentMessage(myImage,model.getMessages(),myName);
} else if (model.getFrom().equals(friendId))
{
holder.fillReceivedMessage(Image,model.getMessages(),Name);
}
}
#NonNull
#Override
public MessagesHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_sent_message,parent,false);
return new MessagesHolder(view,parent.getContext());
}
};
mMessagesList.setAdapter(mAdapter);
mAdapter.startListening();
mRefresh.setRefreshing(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.block_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.bt_menu_block:
blockUser();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void blockUser() {
new AlertDialog.Builder(SentMessagesActivity.this)
.setTitle(getString(R.string.block_this_person))
.setMessage(R.string.would_u_like_to_block)
.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
yesBlock();
}
})
.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
private void yesBlock() {
mMyRef.child(friendId).child(App_Constants.TYPE).setValue(App_Constants.BLOCKED_FROMME).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful())
{
mFriendContacts.child(myId).child(App_Constants.TYPE).setValue(App_Constants.BLOCKED).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful())
{
mMyMessagesRef.removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful())
{
mFriendMessagesRef.removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
App_Utilities.startEndActivity(SentMessagesActivity.this,MainActivity.class);
}
});
}
}
});
}
}
});
}
}
});
}
private void openProfile()
{
Intent intent = new Intent(SentMessagesActivity.this,UserActivity.class);
intent.putExtra(App_Constants.FRIEND_ID,friendId);
startActivity(intent);
}
public void openKeyboard(View view)
{
((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE))
.showSoftInput(mMessage, InputMethodManager.SHOW_FORCED);
}
}
this is happening on some mobiles like samsung
but working fine in others
Add your
Button mSend;
#BindView(R.id.tb_sent_Messages)
Toolbar mToolbar;
#BindView(R.id.rv_sent_messages)
RecyclerView mMessagesList;
#BindView(R.id.et_sent_messages)
EditText mMessage;
#BindView(R.id.srl_sent)
SwipeRefreshLayout mRefresh;
Put the logic above or initialize the widgets and button without butterknife, in the onCreate() function
I want to show Firebase data filtered by userID. But the app crashes and after debugging it shows a NullPointerException on the Firebase adapter. What to do? I am implementing it in fragment. I am not pasting the imported libraries.
Here is my code:
public class MyPosts extends Fragment{
private RecyclerView postList;
private DatabaseReference mDatabase;
private DatabaseReference mDatabaseAppriciate;
private DatabaseReference mDatabaseDisgrace;
private LinearLayoutManager layoutManager;
private FirebaseAuth mAuth= FirebaseAuth.getInstance();
private DatabaseReference mDatabaseCurrentUser;
public Query mQueryCurrentUser=null;
//private static final String TAG = "MyActivity";
private boolean mProcessAppriciate=false;
private boolean mProcessDisgrace=false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
View rootView = inflater.inflate(R.layout.allposts, container, false);
mDatabase= FirebaseDatabase.getInstance().getReference().child("Posts");
mDatabaseAppriciate=FirebaseDatabase.getInstance().getReference().child("Appriciate");
mDatabaseDisgrace=FirebaseDatabase.getInstance().getReference().child("Disgrace");
mDatabase.keepSynced(true);
mDatabaseAppriciate.keepSynced(true);
mDatabaseDisgrace.keepSynced(true);
//EXPERIMENT WITH LISTVIEW STARTS
postList=(RecyclerView) rootView.findViewById(R.id.postList);
postList.setHasFixedSize(true);
layoutManager=new LinearLayoutManager(getActivity());
layoutManager.setReverseLayout(true);
postList.setHasFixedSize(true);
postList.setLayoutManager(layoutManager);
postList.getRecycledViewPool().clear();
//EXPERIMENT WITH LISTVIEW ENDS
return rootView;
}
#Override
public void onStart() {
super.onStart();
//EXP CODE STARTS
FirebaseAuth.getInstance().addAuthStateListener(new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
mDatabaseCurrentUser=FirebaseDatabase.getInstance().getReference().child("Posts");
String currentUserId=user.getUid();
mQueryCurrentUser=mDatabaseCurrentUser.orderByChild("uid").equalTo(currentUserId);
}else{
}
}
});
//EXP CODE ENDS
FirebaseRecyclerAdapter<Posts,PostViewHolder> firebaseRecyclerAdapter= new FirebaseRecyclerAdapter<Posts,PostViewHolder>(
Posts.class,
R.layout.single_post,
PostViewHolder.class,
mQueryCurrentUser
) {
#Override
protected void populateViewHolder(final PostViewHolder viewHolder, final Posts model, final int position) {
final String post_key=getRef(position).getKey();
viewHolder.setTitle(model.getTitle());
viewHolder.setDescription(model.getDescription());
viewHolder.setProfileName(model.getProfilename());
viewHolder.setImage(getContext(),model.getImage());
viewHolder.getLayoutPosition();
viewHolder.setAppriciateButton(post_key);
viewHolder.setDisgraceButton(post_key);
//Share click code below
viewHolder.Share.setOnClickListener(new View.OnClickListener() {
CallbackManager callbackManager;
ShareDialog shareDialog;
#Override
public void onClick(View v) {
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
shareDialog = new ShareDialog(MyPosts.this);
if (ShareDialog.canShow(ShareLinkContent.class)) {
ShareLinkContent content = new ShareLinkContent.Builder()
.setContentTitle(model.getTitle())
.setContentDescription(model.getDescription())
.setImageUrl(Uri.parse(model.getImage()))
.setContentUrl(Uri.parse("https://developers.facebook.com"))
.build();
shareDialog.show(content);
shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException error) {
}
});
}
}
});
//Share click code ends above
//Appriciate button on click event below
viewHolder.Appriciate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProcessAppriciate=true;
mDatabaseAppriciate.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (mProcessAppriciate) {
if (dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())) {
mDatabaseAppriciate.child(post_key).child(mAuth.getCurrentUser().getUid()).removeValue();
mProcessAppriciate = false;
}else {
mDatabaseAppriciate.child(post_key).child(mAuth.getCurrentUser().getUid()).setValue(mAuth.getCurrentUser().getDisplayName());
mProcessAppriciate = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
//Appriciate button click event CODE ENDS
//Disgrace Button Click Event Code Starts
viewHolder.Disgrace.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProcessDisgrace=true;
mDatabaseDisgrace.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (mProcessDisgrace) {
if (dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())) {
mDatabaseDisgrace.child(post_key).child(mAuth.getCurrentUser().getUid()).removeValue();
mProcessDisgrace = false;
} else {
mDatabaseDisgrace.child(post_key).child(mAuth.getCurrentUser().getUid()).setValue(mAuth.getCurrentUser().getDisplayName());
mProcessDisgrace = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
//Disgrace Button Click code Ends
}
};
postList.setAdapter(firebaseRecyclerAdapter);
//test code
firebaseRecyclerAdapter.notifyDataSetChanged();
}
public static class PostViewHolder extends RecyclerView.ViewHolder{
View mView;
Button Appriciate;
Button Disgrace;
Button Share;
DatabaseReference mDatabaseAppriciate;
DatabaseReference mDatabaseDisgrace;
FirebaseAuth mAuth;
public PostViewHolder(View itemView) {
super(itemView);
mView=itemView;
Appriciate=(Button) mView.findViewById(R.id.appriciate);
Disgrace=(Button) mView.findViewById(R.id.disgraceful);
Share=(Button) mView.findViewById(R.id.share);
mDatabaseAppriciate=FirebaseDatabase.getInstance().getReference().child("Appriciate");
mDatabaseDisgrace=FirebaseDatabase.getInstance().getReference().child("Disgrace");
mAuth=FirebaseAuth.getInstance();
mDatabaseAppriciate.keepSynced(true);
mDatabaseDisgrace.keepSynced(true);
}
public void setAppriciateButton(final String post_key){
mDatabaseAppriciate.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())){
Appriciate.setBackgroundColor(Color.GRAY);
Appriciate.setText("Appriciated");
}else{
Appriciate.setBackgroundColor(Color.GREEN);
Appriciate.setText("APPRICIATE");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
//SET DISGRACE BUTTON CODE BELOW
public void setDisgraceButton(final String post_key){
mDatabaseDisgrace.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())){
Disgrace.setBackgroundColor(Color.GRAY);
Disgrace.setText("Disgraced");
}else{
Disgrace.setBackgroundColor(Color.RED);
Disgrace.setText("DISGRACE");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
//SET DISGRACE BUTTON CODE ENDS
//Setting the title to the AllActivity
public void setTitle(String title){
TextView postTitle=(TextView) mView.findViewById(R.id.allPostTitle);
postTitle.setText(title);
}
public void setDescription(String description){
TextView postDescription=(TextView) mView.findViewById(R.id.allPostDescription);
postDescription.setText(description);
}
//PROFILE NAME EXPERIMENT
public void setProfileName(String profilename){
TextView postName=(TextView) mView.findViewById(R.id.profileName);
postName.setText(profilename);
}
public void setImage(final Context context, final String image) {
final ImageView postImage=(ImageView) mView.findViewById(R.id.allPostImage);
with(context).load(image).networkPolicy(NetworkPolicy.OFFLINE).into(postImage, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(context).load(image).resize(500,700).into(postImage);
}
});
}
//THREADING EXPERIMENT CODE
}
}
I'm building an app which will show videos stored on firebase. The list of videos needs to be paginated fetching most recent 20 videos at a time.
Here is the code I thought would work
private void getVideos() {
Query videosQuery = FirebaseUtil.getVideosRef();
videosQuery.startAt(0);
videosQuery.endAt(1);
ChildEventListener videosChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String date = dataSnapshot.getKey();
String temp = date;
}
#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) {
Log.d(tag, "database error");
}
};
ValueEventListener videoValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String date = dataSnapshot.getKey();
String temp = date;
long count = dataSnapshot.getChildrenCount();
String value = dataSnapshot.getValue().toString();
temp = value;
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(tag, "database error");
}
};
// videosQuery.addChildEventListener(videosChildEventListener);
videosQuery.addValueEventListener(videoValueEventListener);
}
But above code retrieves entire list of videos instead of limited videos. How can pagination be implemented.
Below is the code I'm using for pagination which shows the latest node first.
public void getImages() {
Query imagesQuery = FirebaseDatabase.getInstance().getReference().child("englishDps").child(mChildName).orderByKey().limitToLast(21);
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Image image = dataSnapshot.getValue(Image.class);
image.setNodeKey(dataSnapshot.getKey());
mTempImages.add(image);
if (mTempImages.size() == 21) {
mLastKey = mTempImages.get(0).getNodeKey();
Collections.reverse(mTempImages);
mTempImages.remove(mTempImages.size() - 1);
mImages.addAll(mTempImages);
setAdapter();
}
}
#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) {
if (isAdded()) {
Toast.makeText(getActivity(), "Problem loading more images...", Toast.LENGTH_LONG).show();
}
}
};
imagesQuery.addChildEventListener(childEventListener);
}
#Override
public void getMoreImages() {
if (!mGettingMoreImages) {
mGettingMoreImages = true;
Query imagesQuery = FirebaseDatabase.getInstance().getReference("englishDps").child(mChildName).orderByKey().endAt(mLastKey).limitToLast(21);
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Image image = dataSnapshot.getValue(Image.class);
image.setNodeKey(dataSnapshot.getKey());
mMoreImages.add(image);
if (mMoreImages.size() == 21) {
mLastKey = mMoreImages.get(0).getNodeKey();
Collections.reverse(mMoreImages);
mMoreImages.remove(mMoreImages.size() - 1);
mImages.addAll(mMoreImages);
mMoreImages.clear();
mGettingMoreImages = false;
mImagesAdapter.notifyDataSetChanged();
return;
}
if (mLastKey.equalsIgnoreCase(image.getNodeKey())) {
Collections.reverse(mMoreImages);
mImages.addAll(mMoreImages);
mMoreImages.clear();
mGettingMoreImages = false;
mImagesAdapter.onNoMoreImages();
;
mImagesAdapter.notifyDataSetChanged();
}
}
#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) {
if (isAdded()) {
Toast.makeText(getActivity(), "Problem loading more images...", Toast.LENGTH_LONG).show();
}
}
};
imagesQuery.addChildEventListener(childEventListener);
}
}
I have following method to paginate through a firebase realtime database node:
private void getUsers(String nodeId) {
Query query;
if (nodeId == null)
query = FirebaseDatabase.getInstance().getReference()
.child(Consts.FIREBASE_DATABASE_LOCATION_USERS)
.orderByKey()
.limitToFirst(mPostsPerPage);
else
query = FirebaseDatabase.getInstance().getReference()
.child(Consts.FIREBASE_DATABASE_LOCATION_USERS)
.orderByKey()
.startAt(nodeId)
.limitToFirst(mPostsPerPage);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserModel user;
List<UserModel> userModels = new ArrayList<>();
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
userModels.add(userSnapshot.getValue(UserModel.class));
}
mAdapter.addAll(userModels);
mIsLoading = false;
}
#Override
public void onCancelled(DatabaseError databaseError) {
mIsLoading = false;
}
});
}
Every time I reach the bottom of the paginated data, I call the getUsers(mAdapter.getLastItemId()); and then it brings the next set of records.
I have written a complete guide with open source sample app on this that you can check at https://blog.shajeelafzal.com/2017/12/13/firebase-realtime-database-pagination-guide-using-recyclerview/
You want to be using the limitToFirst/limitToLast methods to retrieve a limited number of results.
videosQuery.orderByKey().limitToFirst(20)
https://www.firebase.com/docs/web/api/query/limittofirst.html
You should really consider changing the naming convention of your videos to include leading 0s (i.e. video01, video02... video10, video11) because the above code will display them exactly as you have them above (which I assume is out of order?)
Alternatively, if you're adding the videos via Java, you could just let firebase create the uniqueids via push(). The uniqueid are generated in a way that they'll sort chronilogically, which sounds like it'll suit your need to grab the most recent(ly added?) videos.
https://www.firebase.com/docs/web/api/firebase/push.html
mPageEndOffset = 0;
mPageLimit = 10;
mPageEndOffset += mPageLimit;
deviceListQuery = mDatabase.child("users")
.orderByChild("id").limitToFirst(mPageLimit).startAt(mPageEndOffset);
deviceListQuery.addValueEventListener(YourActivity.this);
You can achieve it by using Firebase database paging library as below code...
In this code, I have shown Post as an data model item and PostViewHolder as ViewHolder
//Initialize RecyclerView
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager mManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mManager);
//Initialize Database
mDatabase = FirebaseDatabase.getInstance().getReference().child("posts");
//Initialize PagedList Configuration
PagedList.Config config = new PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(5)
.setPageSize(10)
.build();
//Initialize FirebasePagingOptions
DatabasePagingOptions<Post> options = new DatabasePagingOptions.Builder<Post>()
.setLifecycleOwner(this)
.setQuery(mDatabase, config, Post.class)
.build();
//Initialize Adapter
mAdapter = new FirebaseRecyclerPagingAdapter<Post, PostViewHolder>(options) {
#NonNull
#Override
public PostViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new PostViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false));
}
#Override
protected void onBindViewHolder(#NonNull PostViewHolder holder,
int position,
#NonNull Post model) {
holder.setItem(model);
}
#Override
protected void onLoadingStateChanged(#NonNull LoadingState state) {
switch (state) {
case LOADING_INITIAL:
case LOADING_MORE:
// Do your loading animation
mSwipeRefreshLayout.setRefreshing(true);
break;
case LOADED:
// Stop Animation
mSwipeRefreshLayout.setRefreshing(false);
break;
case FINISHED:
//Reached end of Data set
mSwipeRefreshLayout.setRefreshing(false);
break;
case ERROR:
retry();
break;
}
}
#Override
protected void onError(#NonNull DatabaseError databaseError) {
super.onError(databaseError);
mSwipeRefreshLayout.setRefreshing(false);
databaseError.toException().printStackTrace();
}
};
//Set Adapter to RecyclerView
mRecyclerView.setAdapter(mAdapter);
Just visit this below URL for reference
https://firebaseopensource.com/projects/patilshreyas/firebaserecyclerpagination/app/readme.md/
Here you will find implementation of library which helps to implement Pagination of firebase data in RecyclerView
I hope this will help you!
This is how I implemented pagination from firebase database. Consider a case if we have 100 messages. So I first load last 20 messages from firebase i.e. 81 to 100. Then on scroll up I call getMoreMessages() function to load next 20 messages which are 61 to 80 and so on.
public class ChatActivity extends Activity {
String chat_id = "";
long mTotalChildren = 0;
boolean loading = false;
ChildEventListener childEventListenerMain, childEventListenerPager;
ChatActivity mContext = ChatActivity.this;
MessageAdapter messageAdapter;
#BindView(R.id.pb_messages)
ProgressBar pb_messages;
#BindView(R.id.ll_audio)
LinearLayout llAudio;
#BindView(R.id.tv_record_time)
AppCompatTextView tvRecordTime;
#BindView(R.id.tv_cancel)
AppCompatTextView tvCancel;
#BindView(R.id.iv_send)
AppCompatImageView ivSend;
#BindView(R.id.iv_record)
AppCompatImageView ivRecord;
#BindView(R.id.ab_layout)
AppBarLayout abLayout;
#BindView(R.id.messages)
RecyclerView rvMessages;
#BindView(R.id.iv_chat_icon)
SimpleDraweeView ivChatIcon;
#BindView(R.id.iv_camera)
AppCompatImageView ivCamera;
#BindView(R.id.iv_gallery)
AppCompatImageView ivGallery;
#BindView(R.id.message_input)
AppCompatEditText messageInput;
#BindView(R.id.tv_send)
AppCompatTextView tvSend;
#BindView(R.id.toolbar_title)
AppCompatTextView toolbarTitle;
#BindView(R.id.toolbar_status)
AppCompatTextView toolbarStatus;
#BindView(R.id.ll_send)
LinearLayout llSend;
int categoryId, senderId, receiverId, offerId;
String mLastKey;
LinearLayoutManager layoutManager;
private ArrayList<MessageModel> messageArrayList = new ArrayList<>();
private ArrayList<MessageModel> tempMessageArrayList = new ArrayList<>();
#Override
public int getLayoutId() {
return R.layout.activity_chat;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
messageAdapter = new MessageAdapter(mContext, messageArrayList) {
};
layoutManager = new LinearLayoutManager(mContext);
rvMessages.setLayoutManager(layoutManager);
rvMessages.setItemAnimator(new DefaultItemAnimator());
rvMessages.setAdapter(messageAdapter);
rvMessages.setHasFixedSize(true);
rvMessages.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (messageArrayList.size() >= 20 &&
!loading && layoutManager.findFirstVisibleItemPosition() == 0 && messageArrayList.size() < mTotalChildren) {
loading = true;
getMoreMessages();
}
}
});
messageAdapter.notifyDataSetChanged();
//used to scroll up recyclerview when keyboard pops up
rvMessages.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View view, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom < oldBottom) {
rvMessages.postDelayed(new Runnable() {
#Override
public void run() {
rvMessages.scrollToPosition(messageArrayList.size() - 1);
}
}, 100);
}
}
});
loading = true;
getMessages();
}
public void getMessages() {
FirebaseDatabase.getInstance().getReference().child(pathtomsgs).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e("childrenCount", String.valueOf(+dataSnapshot.getChildrenCount()));
mTotalChildren = dataSnapshot.getChildrenCount();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Query messageQuery = FirebaseDatabase.getInstance().getReference().child(pathtomsgs).limitToLast(20);
childEventListenerMain = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
loading = true;
MessageModel messageModel = dataSnapshot.getValue(MessageModel.class);
if (messageModel != null) {
messageModel.chat_id = chat_id;
messageModel.message_id = dataSnapshot.getKey();
messageArrayList.add(messageModel);
messageAdapter.notifyDataSetChanged();
mLastKey = messageArrayList.get(0).message_id;
rvMessages.scrollToPosition(messageArrayList.size() - 1);
}
}
#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) {
Toast.makeText(mContext, "Problem loading more images...", Toast.LENGTH_LONG).show();
}
};
messageQuery.addChildEventListener(childEventListenerMain);
ValueEventListener messageChildSINGLEValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
pb_messages.setVisibility(View.GONE);
System.out.println("We're done loading messages " + dataSnapshot.getChildrenCount() + " items");
loading = false;
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
messageQuery.addListenerForSingleValueEvent(messageChildSINGLEValueEventListener);
}
public void getMoreMessages() {
tempMessageArrayList.clear();
Query messageQuery = FirebaseDatabase.getInstance().getReference().child(pathtomsgs).orderByKey().endAt(mLastKey).limitToLast(20);
childEventListenerPager = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
loading = true;
MessageModel messageModel = dataSnapshot.getValue(MessageModel.class);
if (messageModel != null) {
messageModel.chat_id = chat_id;
messageModel.message_id = dataSnapshot.getKey();
tempMessageArrayList.add(messageModel);
}
}
#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) {
Toast.makeText(mContext, "Problem loading more images...", Toast.LENGTH_LONG).show();
}
};
messageQuery.addChildEventListener(childEventListenerPager);
ValueEventListener messageChildSINGLEValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("We're done loading messages " + dataSnapshot.getChildrenCount() + " items");
tempMessageArrayList.remove(tempMessageArrayList.size() - 1);
messageArrayList.addAll(0, tempMessageArrayList);
mLastKey = messageArrayList.get(0).message_id;
messageAdapter.notifyDataSetChanged();
//rvMessages.scrollToPosition(20);
layoutManager.scrollToPositionWithOffset(19, 0);
loading = false;
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
messageQuery.addListenerForSingleValueEvent(messageChildSINGLEValueEventListener);
}
#Override
protected void onDestroy() {
FirebaseDatabase.getInstance().getReference().child(pathtomsgs).removeEventListener(childEventListenerPager);
FirebaseDatabase.getInstance().getReference().child(pathtomsgs).removeEventListener(childEventListenerMain);
super.onDestroy();
}
}
Android paging library can be used to implement pagination for data fetched from firebase database. Data is displayed in recycler view and paging component fetches pages in response to user scroll events.
Paging data source calls your firebase DAO object passing query parameters for the page to be displayed and results are passed back to paging component using callback provided to it.
Here is a complete example for reference http://www.zoftino.com/firebase-pagination-using-android-paging-library
accepted answear dos not work when less then the max. itmes (21) in database.
this is my solution build on the accepted answer:
0)set variables
private String lastMessageKey;
private int totalItemCount;
private int lastVisibleItem;
private boolean isLoadingMoreFollowers = false;
private boolean hasMoreItems = true;
private boolean hasShownNoMoreItemsToast = false;
private boolean initialLoad = true;
private final int MAX_LOAD_ITEMS = 11;
private final int VISIBLE_TRESHOLD = 1;
1) set a listener:
private void setMessageListener() {
if (childEventListener == null) {
mmessageArrayList.clear();
final ArrayList<Mmessage> tempMmessages = new ArrayList<>();
query = mDatabaseInstace.getReference().child(chat1).child(F.CHATS).child(F.MESSAGES).orderByKey().limitToLast(MAX_LOAD_ITEMS-1);
childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d(TAG, "onChildAdded: -----------------> " + dataSnapshot);
Log.d(TAG, "onChildAdded: -----------------> " + s);
tempMmessages.add(dataSnapshot.getValue(Mmessage.class));
preloadMessagePics(tempMmessages);
if (initialLoad) {
lastMessageKey = tempMmessages.get(0).getMessagePushKey();
initialLoad = false;
}
mmessageArrayList.add(tempMmessages.size()-1, tempMmessages.get(0));
messageAdapter.notifyDataSetChanged();
tempMmessages.clear();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d(TAG, "onChildChanged: --------------------------------->");
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved: ---------------------------------->");
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d(TAG, "onChildMoved: ------------------------------------>");
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, "onCancelled: ------------------------------------->");
}
};
query.addChildEventListener(childEventListener);
}
}
2) set load more listener:
private void setLoadMoreListener(){
setup.RV_messages.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!isLoadingMoreFollowers && totalItemCount <= (lastVisibleItem+VISIBLE_TRESHOLD) && (totalItemCount >= MAX_LOAD_ITEMS-1)){
if (hasMoreItems) {
getMoreMessages();
Toast.makeText(homeActivity, "load more items", Toast.LENGTH_SHORT).show();
}else {
if (!hasShownNoMoreItemsToast) {
Toast.makeText(homeActivity, "has no more items", Toast.LENGTH_SHORT).show();
hasShownNoMoreItemsToast = true;
}
}
}
}
});
}
3) get more items:
private void getMoreMessages(){
final ArrayList<Mmessage> tempMmessages = new ArrayList<>();
isLoadingMoreFollowers = true;
loadMoreQuery = mDatabaseInstace.getReference().child(chat1).child(F.CHATS).child(F.MESSAGES).orderByKey().endAt(lastMessageKey).limitToLast(MAX_LOAD_ITEMS);
loadMoreChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
tempMmessages.add(dataSnapshot.getValue(Mmessage.class));
preloadMessagePics(tempMmessages);
if (tempMmessages.size() == MAX_LOAD_ITEMS){
lastMessageKey = tempMmessages.get(0).getMessagePushKey();
Collections.reverse(tempMmessages);
tempMmessages.remove(0);
mmessageArrayList.addAll(tempMmessages);
isLoadingMoreFollowers = false;
messageAdapter.notifyDataSetChanged();
tempMmessages.clear();
return;
}
if (lastMessageKey.equalsIgnoreCase(tempMmessages.get(tempMmessages.size()-1).getMessagePushKey())){
Collections.reverse(tempMmessages);
tempMmessages.remove(0);
mmessageArrayList.addAll(tempMmessages);
isLoadingMoreFollowers = false;
hasMoreItems = false;
messageAdapter.notifyDataSetChanged();
tempMmessages.clear();
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
loadMoreQuery.addChildEventListener(loadMoreChildEventListener);
}
have fun!!
If you want to get list from firebase realtime database descending with pagination you need use smth like this:
Query query = myRef.child("stories").orderByChild("takenAt").endAt(1600957136000L).limitToLast(30);
Full code, two requests
List<Story> storyList = new ArrayList<>();
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference();
//first request will be look like this
Query query = myRef.child("stories").orderByChild("takenAt").endAt(1600957136000L).limitToLast(30);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Story story = snapshot.getValue(Story.class);
storyList.add(story);
}
}
Collections.reverse(storyList);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e("ptg", "onCancelled: ", error.toException());
}
});
//second request
long lastTakenAtInTheStoryList = storyList.get(storyList.size()-1).getTakenAt();
Query query2 = myRef.child("stories").orderByChild("takenAt").endAt(lastTakenAtInTheStoryList).limitToLast(30);
query2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Story story = snapshot.getValue(Story.class);
storyList.add(story);
}
}
Collections.reverse(storyList);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e("ptg", "onCancelled: ", error.toException());
}
});
In the past (but no longer) a question regarding implementing Pagination to a query on Firestore was marked as a duplicate of this question I will answer for FireStore here.
Paginate a query on android Firestore
Query query = db.collection("cities")
.orderBy("population")
.limit(25);
Query next = query;
private void loadCities() {
query = next;
query.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
// Get the last visible document
DocumentSnapshot lastVisible =
documentSnapshots.getDocuments()
.get(documentSnapshots.size() -1);
// Construct a new query starting at this document,
// get the next 25 cities.
next = db.collection("cities")
.orderBy("population")
.startAfter(lastVisible)
.limit(25);
}
});
}
Now just call the loadCities() method whenever you need to load more cities.