Asked  7 Months ago    Answers:  5   Viewed   81 times

I am trying to add a timestamp field in an Android client with Firebase Firestore.

According to the documentation:

Annotation used to mark a Date field to be populated with a server timestamp. If a POJO being written contains null for a @ServerTimestamp-annotated field, it will be replaced with a server-generated timestamp.

But when I try it:

@ServerTimestamp
Date serverTime = null; // I tried both java.util.Date and java.sql.Date

//...

Map<String, Object> msg = new HashMap<>();
// ... more data
msg.put("timestamp", serverTime);

On the Cloud Firestore database this field is always null.

 Answers

21

That is not the correct way of how to add the time and date to a Cloud Firestore database. The best practice is to have a model class in which you can add a date field of type Date together with an annotation. This is how your model class should look like:

import java.util.Date;

public class YourModelClass {
    @ServerTimestamp
    private Date date;

    YourModelClass() {}

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

When you create on object of YourModelClass class, there is no need to set the date. Firebase servers will read your date field, as it is a ServerTimestamp (see the annotation), and it will populate that field with the server timestamp accordingly.

Another approach would be to use FieldValue.serverTimestamp() method like this:

Map<String, Object> map = new HashMap<>();
map.put("date", FieldValue.serverTimestamp());
docRef.update(map).addOnCompleteListener(new OnCompleteListener<Void>() {/* ... */}
Tuesday, June 1, 2021
 
Raef
answered 7 Months ago
74

You can synchronously load data, because a DocumentReference.get() returns a Task. So you can just wait on that task.

If I do something like:

    val task: Task<DocumentSnapshot> = docRef.get()

then I can wait for it to complete by doing

val snap: DocumentSnapshot = Tasks.await(task)

This is useful when piplining other operations together after the get() with continuations which may take a little while:

val task: Task = docRef.get().continueWith(executor, continuation)

Above, I am running a continuation on a separate executor, and I can wait for it all to complete with Tasks.await(task).

See https://developers.google.com/android/guides/tasks

Note: You can't call Tasks.await() on your main thread. The Tasks API specifically checks for this condition and will throw an exception.

There is another way to run synchronously, using transactions. See this question.

Tuesday, July 20, 2021
 
Markol
answered 5 Months ago
14

A successfully completed task will never pass null for the DocumentSnapshot. If the requested document does not exist, you'll get an empty snapshot. This means that:

  • Calling document.exists() returns false
  • Calling document.getData() throws an exception

So there is indeed no reason to check if document != null before calling document.exists().

Friday, August 6, 2021
 
csi
answered 4 Months ago
csi
10

It turned out to be an issue with the Firestore Query. Previously, I had used:

mQuery = mFirestore.collection("courses").whereEqualTo("name", true).limit(LIMIT);

However, it appears that you must use the orderBy() method when making a Firestore Query. Using the following did the trick:

mQuery = mFirestore.collection("courses").orderBy("name").limit(LIMIT);

Now my data is showing up in the RecyclerView as anticipated.

Friday, September 3, 2021
 
neon29
answered 3 Months ago
55

OK, I managed to find the solution by myself, it took me a lot of time to figure it out so I thought it would be a good idea to share the solution in case someone gets the same issue.

So the problem came from the fact that I used this line in my AndroidManifest.xml (inside <application> tag) :

tools:node="replace"

This had to be removed or changed by the following :

tools:node="merge"

Otherwise, Firebase will not work in your app. At least, it's how I fixed my app to finally get a valid token!

Hope this will help someone else!

Tuesday, October 12, 2021
 
CAMason
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share