I'm creating a chat app and I want some way to keep track of the messages. I've already read the following threads on the topic:
Firebase firestore collection count
How to get a count of number of documents in a collection with Cloud Firestore
How to keep track of listeners in Firebase on Android?
And I manage to get a count, it works, but the counter starts over every time I close the app?
I have this method to find the number of Docs in a Firestore collection:
public void numberOfMessagesInConversation() {
CollectionReference messageRef = db.collection("users")
.document(userID)
.collection("conversations")
.document("conversation0") //Specified conversation
.collection("messages");
messageRef.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
counter = documentSnapshots.size();
Log.d(TAG, "counter: " + counter);
}
});
}
Then I have another method where I call the method above, add 1 to the counter and return it as a String:
public String createAndReturnMessageSentNumberStringForDocName() {
numberOfMessagesInConversation();
counter++;
String messageNumberForDoc = String.valueOf(counter);
Log.d(TAG, "createAndReturnMessageSentNumberStringForDocName: " + messageNumberForDoc);
return messageNumberForDoc;
}
Lastly, I have a method to upload the message to Firestore, and I use the counted number to name the messages there, by creating names for the documents such as "message 1", "message 2", "message 3" etc. based on the counter.
public void addSentMessageToFirestoreDB(Map<String, Object> messageSent) {
String docNumber = createAndReturnMessageSentNumberStringForDocName();
Log.d(TAG, "docNumber: " + docNumber);
}
When I open the app, and I write the first messages, it correctly ads the messages in chronological order, and it keeps accurately track of the messages. However, when I close the app and re-open it, it starts to count from a lower number? I have defined the counter at the top like so:
int counter;
So I don't reset it to zero during the initiation either.
Here are my log outputs in chronological order:
I'm also confused why the "createAndReturnMessageSentNumberStringForDocName" method seems to be called first in the log? I thought the "numberOfMessagesInConversation" method would run first.
My new code after feedback from Alex Mamo:
public class ChatCloudSentMessageToFirestore {
private static final String TAG = "saveMessageSent";
int messageCounter;
// Initialize Firebase Firestore Database
private FirebaseFirestore db = FirebaseFirestore.getInstance();
// Initialize Firebase Authentification
private FirebaseAuth mAuth = FirebaseAuth.getInstance();
String userID = getCurrentFirebaseUserId();
public String getCurrentFirebaseUserId() {
FirebaseUser user = mAuth.getCurrentUser();
String userID = user.getUid();
return userID;
}
//Specified conversation
CollectionReference messageCollectionRef = db.collection("users")
.document(userID)
.collection("conversations")
.document("conversation0") //Specified conversation
.collection("messages");
private interface FirestoreCallback {
void onCallback(int messageCounter);
}
private void readData(FirestoreCallback firestoreCallback) {
messageCollectionRef.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
messageCounter = documentSnapshots.size();
messageCounter++;
}
});
firestoreCallback.onCallback(messageCounter);
}
public int getMessageCount() {
readData(new FirestoreCallback() {
@Override
public void onCallback(int messageCounter) {
}
});
return messageCounter;
}
public void addSentMessageToFirestoreDB(final Map<String, Object> messageSent) {
WriteBatch batch = db.batch();
DocumentReference chrisSentMessageRef = db.collection("users")
.document("ypiXrobQxuZ0wplN5KO8gJR7Z4w1")
.collection("conversations")
.document("conversation0") //Specified conversation
.collection("messages")
.document("message" + Integer.toString(getMessageCount()) + " (sent)");
DocumentReference friendSentMessageRef = db.collection("users")
.document("LnUDNBVLW3PM7Dd7dbVJgwLzPe03")
.collection("conversations")
.document("conversation0")
.collection("messages")
.document("message" + Integer.toString(getMessageCount()) + " (sent)");
batch.set(chrisSentMessageRef, messageSent);
batch.set(friendSentMessageRef, messageSent);
batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
;
}
});
}
And I'm calling the addSentMessageToFirestoreDB method from a fragment like so:
//Writes the message to the database only
sendMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String textMessage = editTextChatInputBox.getText().toString();
if (textMessage.length() != 0) {
FirebaseUser user = mAuth.getCurrentUser();
String userID = user.getUid();
Map<String, Object> textMessageHashmap = new HashMap<>();
textMessageHashmap.put("From user with ID", userID);
textMessageHashmap.put("Message", textMessage);
textMessageHashmap.put("Message number in conversation", chatCloudSentMessageToFirestore.getMessageCount()
);
chatCloudSentMessageToFirestore.addSentMessageToFirestoreDB(textMessageHashmap);
}
editTextChatInputBox.setText("");
}
});
return rootView;