Update recyclerview item from activity - android

I have built a chat application and I am adding the message sent to the recyclerview before it's delivered. I want to add a status like whatsApp(tick for sent, error if an error has occurred). Here is my code of the send message:
In send message I am doing this:
public void sendMessage(final String myUId, String chatterUId, final String messageType, final String messageText) {
if (messageText != null && !messageText.trim().equals("")) {
//String messageType = "text"; // it is text by default
//To update the conversation entry with latest message
if (convId == null || convId.equals("")) {
//generate push key as the conv Id
convId = myConvRef.push().getKey();
}
final FirebaseDatabase rootDB = FirebaseDatabase.getInstance();
final DatabaseReference messagesReference = rootDB.getReference()
.child(FirebaseValues.MESSAGES_TABLE)
.child(convId);
sentMessagePushKey = messagesReference.push().getKey();
sentMessage = new Message(messageText, messageType, myUId);
messages.add(sentMessage);
messagesKey.add(sentMessagePushKey);
messageET.setText("");
messagesAdapter.notifyDataSetChanged();
messageRv.scrollToPosition(messages.size() - 1);
//Not posting full code due to stackoverflow word restriction
}
loadMessages function is:
private void loadMessages() {
Log.d(TAG, "Inside loadMessages()");
messagesRef = FirebaseDatabase.getInstance().getReference().child(FirebaseValues.MESSAGES_TABLE).child(convId);
Query messagesQuery = messagesRef.limitToLast(TOTAL_ITEM_EACH_LOAD).orderByKey();
messagesQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot ds, #Nullable String s) {
Log.d(TAG, "Current Message Key: " + ds.getKey());
if (itemPos++ == 0) {
lastKey = ds.getKey();
}
Log.d(TAG, "last item key is: " + lastKey);
Message message = ds.getValue(Message.class);
if(!sentMessagePushKey.equals(ds.getKey())){
messages.add(message);
messagesKey.add(ds.getKey());
}
else{
//The message has been updated in db successfully
messagesAdapter.updateSent(true);
}
//messages.add(message);
/*if(topicKey!=null){
messagesKey.add(0,null);
messages.add(0,null);
}*/
messagesAdapter.notifyDataSetChanged();
messageRv.scrollToPosition(messages.size() - 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) {
messagesAdapter.updateSent(false);
}
});
}
when child is added I want to update show the sent tick on the recylerview Item.
MessagesAdapter:
public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.MessageViewHolder> {
//Other content i.e message
private static final int CONTENT = 0;
//Topic content
private static final int TOPIC_TYPE = 1;
//My message
private static final int MY_MESSAGE = 2;
//My Image message
private static final int MY_IMAGE_MESSAGE = 3;
//My Voice note
private static final int MY_VOICE_NOTE = 4;
//Other person's messages
private static final int OTHER_IMAGE_MESSAGE = 5;
private static final int OTHER_VOICE_TYPE = 6;
private static final String TAG = "MessageAdapterTAG" ;
static final int PERMISSION_STORAGE = 99;
private ArrayList<Message> messages;
private Context mContext;
private FirebaseDatabase mDb;
private ArrayList<String> messagesKey;
private String topicKey;
private String convId;
private String myUId;
private boolean tag = false;
float ratingVal = -1;
int noOfRates=0;
public MessagesAdapter(Context context, ArrayList<Message> messages, ArrayList<String> messagesKey,String myUId, String convId, String topicKey) {
mContext = context;
this.messages = messages;
mDb = FirebaseDatabase.getInstance();
this.messagesKey = messagesKey;
this.myUId = myUId;
this.convId = convId;
this.topicKey = topicKey;
}
View view = null;
#Override
public MessagesAdapter.MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType==TOPIC_TYPE){
//User came through topic
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.topic_chat_layout, parent, false);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
AbsListView.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(params);
}
else if(viewType==MY_MESSAGE){
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_bubble_layout, parent, false);
}
else if(viewType==MY_IMAGE_MESSAGE){
//Image message
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_image_message_layout, parent, false);
}
else if(viewType==MY_VOICE_NOTE){
//Voice message
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_voice_message_layout, parent, false);
}
else if(viewType == OTHER_IMAGE_MESSAGE){
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chatter_image_message_layout, parent, false);
}
else if(viewType==OTHER_VOICE_TYPE){
//Voice message
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chatter_voice_message_layout, parent, false);
}
else{
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chatter_chat_bubble_layout, parent, false);
}
return new MessageViewHolder(view, mContext);
}
public void updateSent(boolean sent){
if(sent){
//Message is sent
}
else{
//error occured
}
}
#Override
public void onBindViewHolder(#NonNull final MessageViewHolder holder, int position) {
Message model = messages.get(position);
if(getItemViewType(position)==TOPIC_TYPE){
Log.d(TAG, "Topic Key:"+topicKey);
//Log.d(TAG, "message below topic: " + model.getText());
DatabaseReference topicRef = FirebaseDatabase.getInstance().getReference()
.child(FirebaseValues.TOPICS_TABLE).child(topicKey);
topicRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final Topics topic = dataSnapshot.getValue(Topics.class);
TextView topicTv = holder.mView.findViewById(R.id.topicTextTv);
TextView usernameTv = holder.mView.findViewById(R.id.usernameTv);
TextView timeTv = holder.mView.findViewById(R.id.timestampTv);
CircleImageView userImage = holder.mView.findViewById(R.id.userImg);
if(topic!=null){
final TextView rateTv;
rateTv = holder.mView.findViewById(R.id.ratingTv);
final DatabaseReference ratingRef = FirebaseDatabase.getInstance().getReference()
.child(FirebaseValues.RATING_TABLE)
.child(topic.getUid());
ratingRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Rating rating = dataSnapshot.getValue(Rating.class);
if(rating!=null){
ratingVal = rating.getTotal_rating();
noOfRates = rating.getNo_of_rates();
}
else{
ratingVal = 0;
}
rateTv.setText(String.format("%.1f", ratingVal/noOfRates)+"/5");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
rateTv.setTooltipText(String.format("%.1f", ratingVal/noOfRates)+" average rating from "+ noOfRates + "ratings");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.e(TAG, "Database Error: "+ databaseError.getMessage());
}
});
TextView rateUserTv;
rateUserTv = holder.mView.findViewById(R.id.rateUserTv);
rateUserTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//open rate user Dialog
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
// ...Irrelevant code for customizing the buttons and title
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View dialogView = inflater.inflate(R.layout.rating_layout, null);
final SmileRating smileRating = dialogView.findViewById(R.id.smile_rating);
dialogBuilder.setView(dialogView);
final AlertDialog alertDialog = dialogBuilder.create();
Button submitBtn = dialogView.findViewById(R.id.submitRatingBtn);
submitBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final int rating = smileRating.getRating();
if(ratingVal>=0){
noOfRates+=1;
float newRate = (ratingVal+rating);
Log.d(TAG, "New Rating: "+newRate);
Rating tempRate = new Rating(newRate, noOfRates);
ratingRef.setValue(tempRate).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
DatabaseReference userRatingRef = FirebaseDatabase.getInstance().getReference()
.child(FirebaseValues.USER_TABLE)
.child(topic.getUid())
.child(FirebaseValues.RATING_TABLE)
.child(myUId);
userRatingRef.setValue(rating).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(mContext, "Thanks for rating the conversation", Toast.LENGTH_SHORT).show();
alertDialog.dismiss();
}
});
}
});
}
}
});
alertDialog.show();
}
});
topicTv.setText(topic.getText());
String time = GetTimeAgo.getTimeAgo(topic.getTimestampCreatedLong(), mContext);
timeTv.setText(time);
if(!topic.isSecret()){
holder.setUserImage(topic.getUid(), userImage);
holder.setUsername(topic.getUid(), usernameTv);
}
else{
usernameTv.setText("Anonymous");
}
}
else{
topicTv.setText("Topic not found");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
else if(getItemViewType(position)==MY_IMAGE_MESSAGE){
holder.setImageMessage(convId,messagesKey.get(position), model.getText());
}
else if(getItemViewType((position))==MY_VOICE_NOTE){
holder.setVoiceMessage(convId, messagesKey.get(position), model.getText());
}
else if( getItemViewType(position)==OTHER_IMAGE_MESSAGE){
//to replace sent to received
holder.setImageMessage(convId,messagesKey.get(position), model.getText().replace("Sent","Received"));
}
else if(getItemViewType(position)==OTHER_VOICE_TYPE){
holder.setVoiceMessage(convId, messagesKey.get(position), model.getText().replace("Sent","Received"));
}
else{
holder.setMessage(model.getText(), model.getFrom());
holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
PrettyDialog pd = new PrettyDialog(mContext);
pd.setTitle("Message Options");
pd.addButton(
"Delete Message", // button text
R.color.pdlg_color_white, // button text color
R.color.pdlg_color_red, // button background color
new PrettyDialogCallback() { // button OnClick listener
#Override
public void onClick() {
// Do what you gotta do
}
}
).addButton(
"Retract Message",
R.color.pdlg_color_white,
R.color.pdlg_color_red,
new PrettyDialogCallback() {
#Override
public void onClick() {
// Dismiss
}
}
).addButton(
"Copy", // button text
R.color.pdlg_color_white, // button text color
R.color.pdlg_color_green, // button background color
new PrettyDialogCallback() { // button OnClick listener
#Override
public void onClick() {
// Do what you gotta do
}
}
);
pd.show();
return true;
}
});
Log.d(TAG, "message: " + model.getText());
}
}
#Override
public int getItemCount() {
return messages.size();
}
#Override
public int getItemViewType(int position) {
if(position==0 && topicKey!=null){
//Insert the topic as first element
return TOPIC_TYPE;
}
Message message = messages.get(position);
if(message.getFrom().equals(myUId)){
//Message is mine
if(message.getType().equals(FirebaseValues.IMAGE_TYPE)){
return MY_IMAGE_MESSAGE;
}
else if(message.getType().equals(FirebaseValues.VOICE_NOTE_TYPE)){
return MY_VOICE_NOTE;
}
return MY_MESSAGE;
}
else{
//The message is from other user
if(message.getType().equals((FirebaseValues.IMAGE_TYPE))){
return OTHER_IMAGE_MESSAGE;
}
else if(message.getType().equals(FirebaseValues.VOICE_NOTE_TYPE)){
return OTHER_VOICE_TYPE;
}
}
return CONTENT;
}
I am unable to post holder class code due to the stackoverflow's word limit.
EDIT:
I have solved this problem myself by removing the object from the recycler view and adding it again and them call notifyItemInserted() on recyclerview. If anyone has better solution please do answer

Related

Import an firebase image when i click it in the recyclerView?

What I've done alone so far is to bring up a activity (recyclerView of the products) when I click ImageView 1.
When I click on the image of recyclerView, my goal is to load the image I clicked on ImageView 1 and save it in DB.
How can I get an image?
this is my product's adapter
#NonNull
#Override
public HolderProductCody onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate layout
View view = LayoutInflater.from(context).inflate(R.layout.row_product_seller,parent,false);
return new HolderProductCody(view);
}
#Override
public void onBindViewHolder(#NonNull HolderProductCody holder, int position) {
//get data
final ModelProduct modelProduct = productList.get(position);
String id = modelProduct.getProductId();
String uid = modelProduct.getUid();
String detailAvailable = modelProduct.getDetailAvailable();
String productColor = modelProduct.getProductColor();
String productTpo = modelProduct.getProductTpo();
String productDescription = modelProduct.getProductDescription();
String productCategory = modelProduct.getProductCategory();
String icon = modelProduct.getProductIcon();
String SeasonCategory = modelProduct.getProductSeasonCategory();
String productSeasonCategory = modelProduct.getProductSeasonCategory();
String title = modelProduct.getProductTitle();
String timestamp = modelProduct.getTimestamp();
String originalPrice = modelProduct.getOriginalPrice();
//set data
holder.titleTv.setText(title);
holder.SeasonCategoryTv.setText(SeasonCategory);
holder.tpoTv.setText(productTpo);
holder.colorTv.setText(productColor);
holder.originalPriceTv.setText("$"+originalPrice);
if(detailAvailable.equals("true")){
//product is on discount
holder.tpoTv.setVisibility(View.VISIBLE);
holder.colorTv.setVisibility(View.VISIBLE);
}
else{
//product is not on discount
holder.tpoTv.setVisibility(View.GONE);
holder.colorTv.setVisibility(View.GONE);
}
try{
Picasso.get().load(icon).placeholder(R.drawable.ic_tshirt_black).into(holder.productIconIv);
}
catch(Exception e){
holder.productIconIv.setImageResource(R.drawable.ic_tshirt_black);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
Toast.makeText(context, "클릭됨", Toast.LENGTH_SHORT).show();
//addcodylayout(modelProduct);
}
});
}
private void addcodylayout(ModelProduct modelProduct) {
Dialog dialog = new Dialog(context);
View view = LayoutInflater.from(context).inflate(R.layout.activity_cody_product,null);
dialog.setContentView(view);
dialog.show();
//get data
final String id = modelProduct.getProductId();
String uid = modelProduct.getUid();
String detailAvailable = modelProduct.getDetailAvailable();
String productTpo = modelProduct.getProductTpo();
String productColor = modelProduct.getProductColor();
String productDescription = modelProduct.getProductDescription();
String productCategory = modelProduct.getProductCategory();
String icon = modelProduct.getProductIcon();
String productSeasonCategory = modelProduct.getProductSeasonCategory();
final String title = modelProduct.getProductTitle();
String timestamp = modelProduct.getTimestamp();
String originalPrice = modelProduct.getOriginalPrice();
try{
Picasso.get().load(icon).placeholder(R.drawable.ic_tshirt_black).into(productIconIv);
}
catch(Exception e){
productIconIv.setImageResource(R.drawable.ic_tshirt_black);
}
dialog.show();
}
#Override
public int getItemCount() {
return productList.size();
}
#Override
public Filter getFilter() {
if(filter==null){
filter = new FilterProduct(this,filterList);
}
return filter;
}
class HolderProductCody extends RecyclerView.ViewHolder{
/*holds views of recyclerview*/
private ImageView productIconIv;
private TextView tpoTv, titleTv, SeasonCategoryTv,colorTv,originalPriceTv;
public HolderProductCody(#NonNull View itemView) {
super(itemView);
productIconIv = itemView.findViewById(R.id.productIconIv);
tpoTv = itemView.findViewById(R.id.tpoTv);
titleTv = itemView.findViewById(R.id.titleTv);
SeasonCategoryTv = itemView.findViewById(R.id.categorySeasonTv);
colorTv = itemView.findViewById(R.id.colorTv);
originalPriceTv = itemView.findViewById(R.id.originalPriceTv);
}
}
}
this is my product's activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cody_product);
filterProductBtn = findViewById(R.id.filterProductBtn);
productsRv = findViewById(R.id.productsRv);
filteredProductsTv = findViewById(R.id.filteredProductsTv);
getSupportActionBar().hide();
firebaseAuth = FirebaseAuth.getInstance();
filterProductBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(CodyProductActivity.this);
builder.setTitle("카테고리 선택").setItems(Constants.productCategories1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//get selected item
String selected = Constants.productCategories1[which];
filteredProductsTv.setText(selected);
if (selected.equals("모든 옷")) {
//load all
loadAllProducts();
} else {
//load filtered
loadFilteredProducts(selected);
}
}
}).show();
}
});
}
private void loadFilteredProducts(String selected) {
productList = new ArrayList<>();
//get all products
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.child(firebaseAuth.getUid()).child("Products").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//before getting reset List
productList.clear();
for(DataSnapshot ds: dataSnapshot.getChildren()){
String productCategory = ""+ds.child("productCategory").getValue();
//if selected category matches product category then add in list
if(selected.equals(productCategory)){
ModelProduct modelProduct = ds.getValue(ModelProduct.class);
productList.add(modelProduct);
}
}
//setup adapter
adapterProductCody = new AdapterProductCody(CodyProductActivity.this,productList);
//set adapter
GridLayoutManager layoutManager = new GridLayoutManager(CodyProductActivity.this,3);
productsRv.setLayoutManager(layoutManager);
productsRv.setAdapter(adapterProductCody);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseerror) {
}
});
}
private void loadAllProducts() {
productList = new ArrayList<>();
//get all products
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.child(firebaseAuth.getUid()).child("Products").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//before getting reset List
productList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ModelProduct modelProduct = ds.getValue(ModelProduct.class);
productList.add(modelProduct);
}
//setup adapter
adapterProductCody = new AdapterProductCody(CodyProductActivity.this, productList);
//set adapter
GridLayoutManager layoutManager = new GridLayoutManager(CodyProductActivity.this, 3);
productsRv.setLayoutManager(layoutManager);
productsRv.setAdapter(adapterProductCody);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
The ID value of ImageView1 is topImages.

Firebase Timestamp delay android causing app to crash when first document added to a collection for the first time.(orderby time stamp)

I used Firebase Firestore to create a realtime recycler view with pagination, but the problem is that I am trying to order the documents using Timestamp. When I try to add a new document the app crashes. This only happens when adding the first document in a collection, after that it will work fine.
This is the error I'm getting:
java.lang.IllegalArgumentException: Invalid query. You are trying to start or end a query using a document for which the field 'date_posted' is an uncommitted server timestamp. (Since the value of this field is unknown, you cannot start/end a query with it.)
at com.google.firebase.firestore.Query.boundFromDocumentSnapshot(com.google.firebase:firebase-firestore##21.4.3:758)
at com.google.firebase.firestore.Query.startAfter(com.google.firebase:firebase-firestore##21.4.3:648)
at com.project.alihammoud.foodreviewlb.BottomSheetFragmentComment.loadMore(BottomSheetFragmentComment.java:251)
at com.project.alihammoud.foodreviewlb.BottomSheetFragmentComment$2.onScrolled(BottomSheetFragmentComment.java:191)
at androidx.recyclerview.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:5173)
I have it that when I send a document to the firestore database, it gets its timestamp from the firestore server. I know that there is a delay in assigning the Timestamp so I tried adding a wait before refreshing but that did not work. Any ideas what could work to avoid this issue?
Here is my code:
public class BottomSheetFragmentComment extends BottomSheetDialogFragment {
private Toolbar toolbar;
private String document_id;
private String currentUserID;
private FirebaseAuth auth;
private FirebaseUser currentUser;
private FirebaseFirestore db;
private RecyclerView recyclerView;
private List<CommentInfo> comments_list;
private CommentsAdapter commentsAdapter;
private ImageButton comment_button;
private EditText comment_text;
private DocumentSnapshot lastVisible;
private Boolean isFirstPageFirstLoad = true;
private CommentID commentID;
public BottomSheetFragmentComment(){
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_sheet_comments,container,false);
document_id = this.getArguments().getString("docID");
auth = FirebaseAuth.getInstance();
currentUser = auth.getCurrentUser();
currentUserID = currentUser.getUid();
db = FirebaseFirestore.getInstance();
comments_list = new ArrayList<>();
commentsAdapter = new CommentsAdapter(comments_list);
Query firstQuery = db.collection("Reviews").document(document_id).collection("Comments")
.orderBy("date_posted", Query.Direction.DESCENDING)
.limit(20);
firstQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot documentSnapshot, #Nullable FirebaseFirestoreException e) {
if (e == null){
if (!documentSnapshot.isEmpty()){
if (isFirstPageFirstLoad){
lastVisible = documentSnapshot.getDocuments().get(documentSnapshot.size()-1);
}
for (DocumentChange documentChange: documentSnapshot.getDocumentChanges()){
if (documentChange.getType() == DocumentChange.Type.ADDED){
String commentID = documentChange.getDocument().getId();
CommentInfo commentAdded = documentChange.getDocument().toObject(CommentInfo.class);
if (isFirstPageFirstLoad){
comments_list.add(commentAdded);
}
else {
comments_list.add(0,commentAdded);
}
commentsAdapter.notifyDataSetChanged();
}
else if (documentChange.getType() == DocumentChange.Type.REMOVED){
comments_list.remove(documentChange.getOldIndex());
commentsAdapter.notifyItemRemoved(documentChange.getOldIndex());
}
else if (documentChange.getType() == DocumentChange.Type.MODIFIED){
CommentInfo commentModified = documentChange.getDocument().toObject(CommentInfo.class);
if (documentChange.getOldIndex() == documentChange.getNewIndex()) {
// Item changed but remained in same position
comments_list.set(documentChange.getOldIndex(),commentModified);
commentsAdapter.notifyItemChanged(documentChange.getOldIndex());
}else {
// Item changed and changed position
comments_list.remove(documentChange.getOldIndex());
comments_list.add(documentChange.getNewIndex(),commentModified);
commentsAdapter.notifyItemMoved(documentChange.getOldIndex(),documentChange.getNewIndex());
}
commentsAdapter.notifyDataSetChanged();
}
}
isFirstPageFirstLoad = false;
}
}
}
});
// db.collection("Reviews").document(document_id).collection("Comments")
if (currentUser != null){
//setUpRecyclerView();
recyclerView = view.findViewById(R.id.recycle_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getContext());
mLayoutManager.setReverseLayout(true);
// mLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(commentsAdapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Boolean reachedBottom = !recyclerView.canScrollVertically(-5);
if (reachedBottom){
String desc = lastVisible.getString("comment");
Toast.makeText(getContext(),"Reached: " + desc ,Toast.LENGTH_SHORT).show();
loadMore();
/* final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
}
},5000);*/
}
}
});
}
toolbar = view.findViewById(R.id.toolbar);
toolbar.setTitle("Comments");
toolbar.setTitleTextColor(Color.BLACK);
comment_text = view.findViewById(R.id.comment_text);
comment_button = view.findViewById(R.id.comment_button);
comment_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db.collection("Reviews").document(document_id).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.getResult().exists()){
DocumentReference newComment = db.collection("Reviews").document(document_id).collection("Comments").document();
CommentInfo commentInfo = new CommentInfo();
commentInfo.setUser_id(currentUserID);
commentInfo.setComment(comment_text.getText().toString().trim());
newComment.set(commentInfo);
comment_text.getText().clear();
}
else {
Toast.makeText(getContext(), "This review has been removed, please refresh your feed.", Toast.LENGTH_LONG).show();
}
}
});
}
});
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void loadMore(){
Query nextQuery = db.collection("Reviews").document(document_id).collection("Comments")
.orderBy("date_posted", Query.Direction.DESCENDING)
.startAfter(lastVisible)
.limit(10);
nextQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot documentSnapshot, #Nullable FirebaseFirestoreException e) {
if (e == null){
if (!documentSnapshot.isEmpty()){
lastVisible = documentSnapshot.getDocuments().get(documentSnapshot.size()-1);
for (DocumentChange documentChange: documentSnapshot.getDocumentChanges()){
if (documentChange.getType() == DocumentChange.Type.ADDED){
String commentID = documentChange.getDocument().getId();
CommentInfo commentAdded = documentChange.getDocument().toObject(CommentInfo.class);
comments_list.add(commentAdded);
commentsAdapter.notifyDataSetChanged();
}
else if (documentChange.getType() == DocumentChange.Type.REMOVED){
comments_list.remove(documentChange.getOldIndex());
commentsAdapter.notifyItemRemoved(documentChange.getOldIndex());
}
else if (documentChange.getType() == DocumentChange.Type.MODIFIED){
// modifying
CommentInfo commentModified = documentChange.getDocument().toObject(CommentInfo.class);
if (documentChange.getOldIndex() == documentChange.getNewIndex()) {
// Item changed but remained in same position
comments_list.set(documentChange.getOldIndex(),commentModified);
commentsAdapter.notifyItemChanged(documentChange.getOldIndex());
}else {
// Item changed and changed position
comments_list.remove(documentChange.getOldIndex());
comments_list.add(documentChange.getNewIndex(),commentModified);
commentsAdapter.notifyItemMoved(documentChange.getOldIndex(),documentChange.getNewIndex());
}
commentsAdapter.notifyDataSetChanged();
}
}
}
}
}
});
}
#NonNull #Override public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override public void onShow(DialogInterface dialogInterface) {
BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
setupFullHeight(bottomSheetDialog);
}
});
return dialog;
}
private void setupFullHeight(BottomSheetDialog bottomSheetDialog) {
FrameLayout bottomSheet = (FrameLayout) bottomSheetDialog.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
ViewGroup.LayoutParams layoutParams = bottomSheet.getLayoutParams();
int windowHeight = getWindowHeight();
if (layoutParams != null) {
layoutParams.height = windowHeight;
}
bottomSheet.setLayoutParams(layoutParams);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
private int getWindowHeight() {
// Calculate window height for fullscreen use
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
}
public class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.ViewHolder> {
private Context context;
private FirebaseFirestore db;
public List<CommentInfo> comments_list;
public CommentsAdapter(List<CommentInfo> comments_list){
this.comments_list = comments_list;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_comments,parent,false);
context = parent.getContext();
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
db = FirebaseFirestore.getInstance();
//final String commentID = comments_list.get(position)
String comment = comments_list.get(position).getComment();
holder.setComment(comment);
final String commentUserID = comments_list.get(position).getUser_id();
DocumentReference userData = db.collection("Users").document(commentUserID);
userData.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
if (task.getResult().exists()) {
String firstname = task.getResult().getString("first_name");
String lastname = task.getResult().getString("last_name");
String userPicture = task.getResult().getString("profile_picture");
holder.setUserData(firstname,lastname,userPicture);
}
}
}
});
}
#Override
public int getItemCount() {
return comments_list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private View mView;
private TextView comment, first_name, last_name;
CircleImageView users_profile_picture;
public ViewHolder(#NonNull final View itemView) {
super(itemView);
mView = itemView;
}
public void setComment(String CommentText){
comment = mView.findViewById(R.id.comment);
comment.setText(CommentText);
}
private void setUserData(String firstName, String lastName, String profilePicture){
first_name = mView.findViewById(R.id.first_name);
last_name = mView.findViewById(R.id.last_name);
users_profile_picture = mView.findViewById(R.id.users_profile_picture);
first_name.setText(firstName);
last_name.setText(lastName);
if (profilePicture != null){
Glide.with(context).load(profilePicture).into(users_profile_picture);
}
}
}
}
#IgnoreExtraProperties
public class CommentInfo {
private String user_id;
private String comment;
private #ServerTimestamp Date date_posted;
public CommentInfo(){
}
public CommentInfo(String user_id, String comment, Date date_posted) {
this.user_id = user_id;
this.comment = comment;
this.date_posted = date_posted;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Date getDate_posted() {
return date_posted;
}
public void setDate_posted(Date date_posted) {
this.date_posted = date_posted;
}
}
The error message is:
Invalid query. You are trying to start or end a query using a document for which the field 'date_posted' is an uncommitted server timestamp. (Since the value of this field is unknown, you cannot start/end a query with it.)
So it looks like it comes from this:
Query nextQuery = db.collection("Reviews").document(document_id).collection("Comments")
.orderBy("date_posted", Query.Direction.DESCENDING)
.startAfter(lastVisible)
.limit(10);
From the error message it seems that the date_posted field may have unknown values, in which case you can't query on it.
This comes from:
private #ServerTimestamp Date date_posted;
From this Github issue with multiple comments from Firestore team members, it seems that:
pagination and server-issued time are essentially incompatible

get key position in onBindViewHolder firebase database

I want to get key position in database.
getting error: getRef(position) : Cannot resolve method 'getRef(int)' on
final String post_key = getRef(position).getKey();
this is my code CustomPostAdapter
public class CustomPostAdapter extends RecyclerView.Adapter<CustomPostAdapter.ViewHolder>{
public List<Spacecraft> userList ;
public Context context ;
private boolean mProcessLike = false ;
private DatabaseReference mDatabaseLike ;
// public ImageView imagePostt ;
public CustomPostAdapter(Context context , List<Spacecraft> userList){
this.userList = userList ;
this.context = context;
}
#NonNull
#Override
public CustomPostAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_posts_item, parent,false);
return new CustomPostAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
mDatabaseLike = FirebaseDatabase.getInstance().getReference().child("Likes");
mDatabaseLike.keepSynced(true);
final String post_key = getRef(position).getKey();
final String name = userList.get(position).getName();
final String image_post = userList.get(position).getImage_post();
final String descrip = userList.get(position).getDescrip();
final String hachatg = userList.get(position).getHachtag();
final String user = userList.get(position).getUser();
final String time = userList.get(position).getTime();
//Text Post
holder.nameText.setText(name);
holder.descripText.setText(descrip);
holder.hachtagText.setText(" " + hachatg);
holder.timeText.setText(" " + time);
//Imgae Post if null set Visibtly Gone to ImageView
if (TextUtils.isEmpty(image_post)){
holder.imagePostt.setVisibility(View.GONE);
}else {
//Image Post
Picasso.with(context).load(image_post).into(holder.imagePostt , new Callback() {
#Override
public void onSuccess() {
holder.imagePostt.setVisibility(View.VISIBLE);
}
#Override
public void onError() {
holder.imagePostt.setVisibility(View.GONE);
}
});
}
//Onclick items
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context , ContentActivity.class);
intent.putExtra("NAME_KEY", name);
intent.putExtra("HACHTAG_KEY", hachatg);
intent.putExtra("DESCRIP_KEY", descrip);
intent.putExtra("USER_KEY", user);
intent.putExtra("IMAGE_POST", image_post);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
//Button Like Onclice
holder.mLikeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProcessLike = true;
if (mProcessLike){
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Chek if user already Like or not
if (dataSnapshot.child(post_key).hasChild(user)){
}else {
mDatabaseLike.child(post_key).child(user).setValue("RandomValue");
mProcessLike = false;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
}
#Override
public int getItemCount() {
return userList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
View mView;
public TextView nameText , hachtagText , descripText, urlText , timeText;
public ImageView imagePostt ;
public ImageButton mLikeBtn ;
public ViewHolder(View itemView) {
super(itemView);
mView = itemView;
nameText = (TextView)mView.findViewById(R.id.text_nameProblem);
hachtagText = (TextView)mView.findViewById(R.id.text_nameUser);
// urlText = (TextView)mView.findViewById(R.id.textUrl);
descripText = (TextView)mView.findViewById(R.id.text_Discription);
timeText = (TextView)mView.findViewById(R.id.timeText);
imagePostt = (ImageView)mView.findViewById(R.id.imagePost);
mLikeBtn = (ImageButton)mView.findViewById(R.id.btnLike);
}
}
}
You should be using FirebaseRecyclerAdapter which has the method getRef(). follow this link to learn how to use it
There are two ways in which you can solve this. The first one would be to store the key as a property in your user object and use:
final String key = userList.get(position).getKey();
And the second one would be to simply use FirebaseRecyclerAdapter instead and call:
mFirebaseRecyclerAdapter.getKey(position);
As explained here by #Puf.

cannot fetch values from firebase database

Main activity.java
public class activity_3 extends AppCompatActivity {
TextView question,option_1,option_2,option_3,description,winnner;
NumberProgressBar option_progress1, option_progress2,option_progress3;
int val_1;
int val_2;
int val_3;
DatabaseReference Polldata_3;
String optionOne;
String optionTwo;
String optionThree;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_3);
final String que = getIntent().getExtras().getString("que");
final String des = getIntent().getExtras().getString("des");
optionOne = getIntent().getExtras().getString("option1");
optionTwo = getIntent().getExtras().getString("option2");
optionThree = getIntent().getExtras().getString("option3");
final String id_user = getIntent().getExtras().getString("id");
val_1 = getIntent().getExtras().getInt("val1");
val_2 = getIntent().getExtras().getInt("val2");
val_2 = getIntent().getExtras().getInt("val3");
option_progress1 = (NumberProgressBar) findViewById(R.id.option1_progressbar);
option_progress2 = (NumberProgressBar) findViewById(R.id.option2_progressbar);
option_progress3 = (NumberProgressBar) findViewById(R.id.option3_progressbar);
Polldata_3 = FirebaseDatabase.getInstance().getReference("POll").child("poll_3");
final DatabaseReference answsersave = Polldata_3.child(id_user);
question = (TextView) findViewById(R.id.question_showpoll);
option_1 = (TextView) findViewById(R.id.option_1);
option_2 = (TextView) findViewById(R.id.option_2);
option_3 = (TextView) findViewById(R.id.option_3);
description = (TextView) findViewById(R.id.description_user_3);
winnner = (TextView) findViewById(R.id.winner);
option_1.setText(optionOne);
option_2.setText(optionTwo);
option_3.setText(optionThree);
question.setText(que);
description.setText(des);
option_progress1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
option_progress1.setProgress(val_1+1);
option_progress1.setEnabled(false);
option_progress2.setEnabled(false);
option_progress3.setEnabled(false);
val_1++;
answsersave.child("option_1_value").setValue(val_1);
//winnerdeclare();
}
});
option_progress2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
option_progress2.setProgress(val_2+1);
option_progress1.setEnabled(false);
option_progress2.setEnabled(false);
option_progress3.setEnabled(false);
val_2++;
answsersave.child("option_2_value").setValue(val_2);
// winnerdeclare();
}
});
option_progress3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
option_progress3.setProgress(val_3+1);
option_progress1.setEnabled(false);
option_progress2.setEnabled(false);
option_progress3.setEnabled(false);
val_3++;
// winnerdeclare();
answsersave.child("option_3_value").setValue(val_3);
}
});
}
}
ADAPTER CLASS
public class listview_3 extends AppCompatActivity {
ListView listviewpoll3;
private DatabaseReference Poll_data_3;
List<addpoll_3> addpoll_3List;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview_3);
listviewpoll3 = (ListView) findViewById(R.id.poll_listview_3);
Poll_data_3 = FirebaseDatabase.getInstance().getReference("POll").child("poll_3");
addpoll_3List = new ArrayList<>();
listviewpoll3.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
Intent intent = new Intent(listview_3.this, activity_3.class);
addpoll_3 poll = addpoll_3List.get(position);
final String optionone = poll.getOption_1();
final String optiontwo = poll.getOption_2();
final String optionthree = poll.getOption_3();
final String id_user = poll.getId();
final int value_1 = poll.getOption_1_value();
final int value_2 = poll.getOption_2_value();
final int value_3 = poll.getOption_3_value();
final String question = poll.getQuestion();
final String desp = poll.getDescription();
intent.putExtra("option1",optionone);
intent.putExtra("option2",optiontwo);
intent.putExtra("option3",optionthree);
intent.putExtra("id",id_user);
intent.putExtra("val1",value_1);
intent.putExtra("val2",value_2);
intent.putExtra("val3",value_3);
intent.putExtra("que",question);
intent.putExtra("descp",desp);
startActivity(intent);
}
});
}
#Override
protected void onStart() {
super.onStart();
Poll_data_3.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
addpoll_3List.clear();
for(DataSnapshot pollSnapshot: dataSnapshot.getChildren())
{
addpoll_3 poll = pollSnapshot.getValue(addpoll_3.class);
addpoll_3List.add(poll);
}
poll_list_3 adapter = new poll_list_3(listview_3.this,addpoll_3List);
listviewpoll3.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
list class
public class poll_list_3 extends ArrayAdapter<addpoll_3> {
private Activity context;
private List<addpoll_3> addpoll_3List;
public poll_list_3(Activity context, List<addpoll_3> addpoll_3List) {
super(context, R.layout.list_layout, addpoll_3List);
this.context = context;
this.addpoll_3List = addpoll_3List;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View viewitem = inflater.inflate(R.layout.list_layout,null);
TextView textViewName = (TextView) viewitem.findViewById(R.id.tv);
TextView textViewDesp = (TextView) viewitem.findViewById(R.id.tv1);
final addpoll_3 poll1 = addpoll_3List.get(position);
textViewName.setText(poll1.getQuestion());
textViewDesp.setText(poll1.getDescription());
return viewitem;
}
}
I am making a polling app where user can create a poll which is then stored in the firebase database and retrieved into listview of the app
when the user clicks on the list view he is directed to the the activity where there are number of progressbars
i have added a ON-click listener o the progress bar, So when user clicks on the progressbar the val of that option gets incremented in the database. so when a different user vote on the same poll the value from the database is fetched and value of the current user is added displaying the winner,but problem is the value of the progressbar1 gets the value from the database but the other two keep progress bar values start from 0 every time user clicks on the other two progress bar (ie 2 and 3).
please help
addpoll_3.java
public class addpoll_3 {
String id;
String question;
String description;
String option_1;
String option_2;
String option_3;
int option_1_value;
int option_2_value;
int option_3_value;
public addpoll_3(){}
public addpoll_3(String id, String question, String description, String option_1, String option_2, String option_3, int option_1_value, int option_2_value, int option_3_value) {
this.id = id;
this.question = question;
this.description = description;
this.option_1 = option_1;
this.option_2 = option_2;
this.option_3 = option_3;
this.option_1_value = option_1_value;
this.option_2_value = option_2_value;
this.option_3_value = option_3_value;
}
public String getId() {
return id;
}
public String getQuestion() {
return question;
}
public String getDescription() {
return description;
}
public String getOption_1() {
return option_1;
}
public String getOption_2() {
return option_2;
}
public String getOption_3() {
return option_3;
}
public int getOption_1_value() {
return option_1_value;
}
public int getOption_2_value() {
return option_2_value;
}
public int getOption_3_value() {
return option_3_value;
}
}
code:
Activity_3.java
val_1 = getIntent().getExtras().getInt("val1");
val_2 = getIntent().getExtras().getInt("val2");
val_3 = getIntent().getExtras().getInt("val3");
These were changes to be made
//Read from the database
myRef.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
String value = dataSnapshot.getValue(String.class);
Log.d(TAG, "Value is: " + value);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});

RecyclerView Adapter notify data changed

There is my activity:
public class EventDetailsActivity extends AppCompatActivity {
private Event event;
private ArrayList<User> subscribedUsers;
private RecyclerView mRecyclerView;
private String eventId;
private SubscribedUsersAdapter adapter;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_details);
context = this;
Bundle extras = getIntent().getExtras();
eventId = extras.getString("eventId");
setUpEvent();
}
private void setUpEvent() {
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
final DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("events").child(eventId);
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String eventType = dataSnapshot.child("eventType").getValue().toString();
String description = dataSnapshot.child("description").getValue().toString();
Object object = dataSnapshot.child("startingDate").getValue();
HashMap result = (HashMap) object;
int year = Integer.parseInt(result.get("year").toString());
int month = Integer.parseInt(result.get("month").toString());
int day = Integer.parseInt(result.get("date").toString());
int hour = Integer.parseInt(result.get("hours").toString());
int minute = Integer.parseInt(result.get("minutes").toString());
Date startingDate = new Date(year,month,day,hour,minute,0);
object = dataSnapshot.child("location").getValue();
result = (HashMap) object;
double latitude = Double.parseDouble(result.get("latitude").toString());
double longitude = Double.parseDouble(result.get("longitude").toString());
LatLng location = new LatLng(latitude,longitude);
String userId = dataSnapshot.child("userId").getValue().toString();
String userName = dataSnapshot.child("userName").getValue().toString();
String userPicture = dataSnapshot.child("userPicture").getValue().toString();
subscribedUsers = new ArrayList<User>();
if (dataSnapshot.hasChild("subscribedUsers")) {
mDatabase.child("subscribedUsers").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String userId = childSnapshot.child("userId").getValue().toString();
String name = childSnapshot.child("name").getValue().toString();
String picture = childSnapshot.child("picture").getValue().toString();
User subscribedUser = new User(userId, name, picture);
if (containsUser(subscribedUsers, subscribedUser) == -1) {
subscribedUsers.add(subscribedUser);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
event = new Event(eventId, eventType,description,startingDate,location,userId, userName, userPicture);
setText();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void setText()
{
ImageView mProfilePicture = (ImageView) findViewById(R.id.profilePicture);
if (!EventDetailsActivity.this.isFinishing()) {
Glide
.with(this)
.load(event.getUserPicture())
.into(mProfilePicture);
}
TextView mUserName = (TextView) findViewById(R.id.userName);
mUserName.setText(event.getUserName());
TextView mEventType = (TextView) findViewById(R.id.eventType);
mEventType.setText(event.getEventType());
TextView mDescription = (TextView) findViewById(R.id.description);
mDescription.setText(event.getDescription());
if (!EventDetailsActivity.this.isFinishing()) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapView);
mapFragment.getMapAsync(new OnMapReadyCallback()
{
#Override
public void onMapReady(GoogleMap googleMap) {
googleMap.clear();
googleMap.addMarker(new MarkerOptions().position(event.getLocation()));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(event.getLocation(),12.0f));
}
});
}
TextView mStartingDate = (TextView) findViewById(R.id.startingDate);
Date startingDate = event.getStartingDate();
String displayText = String.valueOf(startingDate.getYear());
int month = startingDate.getMonth() + 1;
if (month/10 == 0)
{
displayText = displayText + ".0" + month;
}
else
{
displayText = displayText + "." + month;
}
if (startingDate.getDate()/10 == 0)
{
displayText = displayText + ".0" + startingDate.getDate();
}
else
{
displayText = displayText + "." + startingDate.getDate();
}
if (startingDate.getHours()/10 == 0)
{
displayText = displayText + ". 0" + startingDate.getHours();
}
else
{
displayText = displayText + ". " + startingDate.getHours();
}
if (startingDate.getMinutes()/10 == 0)
{
displayText = displayText + ":0" + startingDate.getMinutes();
}
else
{
displayText = displayText + ":" + startingDate.getMinutes();
}
mStartingDate.setText(displayText);
setUpRecyclerView();
subscribe();
}
private void setUpRecyclerView() {
adapter = new SubscribedUsersAdapter(this,subscribedUsers);
mRecyclerView.setAdapter(adapter);
}
private void subscribe()
{
FirebaseAuth mAuth = FirebaseAuth.getInstance();
if (mAuth.getCurrentUser() != null) {
final String userId = mAuth.getCurrentUser().getUid();
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("users").child(userId);
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String userName = dataSnapshot.child("name").getValue().toString();
String userPicture = dataSnapshot.child("picture").getValue().toString();
User user = new User(userId, userName, userPicture);
userSubscribe(user);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
else
{
userSubscribe(null);
}
}
private void userSubscribe(final User user) {
Button mSubscribeButton = (Button) findViewById(R.id.subscribeButton);
if (user == null)
{
mSubscribeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(EventDetailsActivity.this, getResources().getString(R.string.logInToSubscribe), Toast.LENGTH_LONG).show();
Intent loginIntent = new Intent(EventDetailsActivity.this, LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(loginIntent);
}
});
}
else if (containsUser(subscribedUsers,user) == -1)
{
mSubscribeButton.setText(getResources().getString(R.string.subscribe));
mSubscribeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("events").child(event.getEventId());
subscribedUsers.add(user);
mDatabase.child("subscribedUsers").setValue(subscribedUsers);
}
});
}
else
{
mSubscribeButton.setText(getResources().getString(R.string.unsubscribe));
mSubscribeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("events").child(event.getEventId());
int position = containsUser(subscribedUsers,user);
subscribedUsers.remove(position);
mDatabase.child("subscribedUsers").removeValue();
mDatabase.child("subscribedUsers").setValue(subscribedUsers);
}
});
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
this.finish();
}
private int containsUser(ArrayList<User> users, User user)
{
for (int i=0; i<users.size(); ++i)
{
if (users.get(i).getUserId().equals(user.getUserId()))
{
return i;
}
}
return -1;
}
}
And my adapter:
public class SubscribedUsersAdapter extends RecyclerView.Adapter<SubscribedUsersAdapter.ViewHolder>{
private Context context;
private ArrayList<User> items;
public SubscribedUsersAdapter(Context context, ArrayList<User> items) {
this.context = context;
this.items = items;
}
protected static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView mProfilePictureView;
public TextView mUserName;
public ViewHolder(View itemView) {
super(itemView);
mProfilePictureView = (ImageView) itemView.findViewById(R.id.profilePictureView);
mUserName = (TextView) itemView.findViewById(R.id.userName);
}
}
#Override
public SubscribedUsersAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_user, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final User item = items.get(position);
Glide
.with(context)
.load(item.getPicture())
.into(holder.mProfilePictureView);
holder.mUserName.setText(item.getName());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent profileIntent = new Intent(context, ProfileActivity.class);
profileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
profileIntent.putExtra("userId", item.getUserId());
context.startActivity(profileIntent);
}
});
}
#Override
public int getItemCount() {
return items.size();
}
}
When the activity starts firstly, the data is displayed well in RecyclerView, but if a user subscribes to the event or unsubscribe from it, the RecyclerView will be empty.
I tried with notifyDataSetChanged, notifyItemRangeInserted, notifyItemRangeRemoved, but none of them worked or I didn't use it well. I don't know.
Thanks for your help!
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String userId = childSnapshot.child("userId").getValue().toString();
String name = childSnapshot.child("name").getValue().toString();
String picture = childSnapshot.child("picture").getValue().toString();
User subscribedUser = new User(userId, name, picture);
if (containsUser(subscribedUsers, subscribedUser) == -1) {
subscribedUsers.add(subscribedUser);
}
}
after that just add this line
adapter.notifyDataSetChanged();

Categories

Resources