0

I'm using Firestore shards to keep track of the number of documents in a collection. How do I convert the task it returns into a String?

My method (same as Firebase Documentation):

public Task<Integer> getCount(final DocumentReference ref) {
    // Sum the count of each shard in the subcollection
    return ref.collection("shards").get()
            .continueWith(new Continuation<QuerySnapshot, Integer>() {
                @Override
                public Integer then(@NonNull Task<QuerySnapshot> task) throws Exception {
                    int count = 0;
                    for (DocumentSnapshot snap : task.getResult()) {
                        Shard shard = snap.toObject(Shard.class);
                        count += shard.count;
                    }
                    Log.d(TAG, Integer.toString(count));
                    return count;
                }
            });
}

correctly logs the count as follows: D/saveMessageSent: 1

However, when I call the getCount method somewhere else like so:

Log.d(TAG, String.valueOf(getCount(counterDocRef)));

then the log output is:

D/saveMessageSent: com.google.android.gms.tasks.zzu@8673e29

I cannot seem to convert it into a String, as it says it's a

com.google.android.gms.tasks.Task<java.lang.Integer>

How do I get around this so when I call getCount it gives me an int I can use?

The Fluffy T Rex
  • 430
  • 7
  • 22

2 Answers2

2

You don't convert Task objects to other types of objects. You use the Task API to receive the result of an asynchronous Task in a callback. For example, if you have a Task, it will yield an Integer in the success callback:

task.addOnSuccessListener(new OnSuccessListener<Integer>() {
    @Override
    public void onSuccess(Integer i) {
        // i is the Integer result of the task.
    }
});
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
0

The return type of your getCount() method, is a Task<Integer> and not an Integer, as you probably thought. It's true that, when initializing the Continuation class, which is actually an anonymous class, the overriding method has the return type an Integer but this is not the return type of your enclosing getCount() method. So this method will never return an Integer object.

When you are trying to use the following statement:

Log.d(TAG, String.valueOf(getCount(counterDocRef)));

It won't print an integer because you are passing to the valueOf() method a Task<Integer> object and not an Integer and that's why you get that weird log statement. What is actually printing, is the actual address of that object from the memory.

To solve this, you should use the value of your count only inside the inner then method. If you want to count all the documents within a collection, please see my answer from this post.

You can also use addOnSuccessListener, as also @Doug Stevenson mentioned in his answer, which is a more simpler and elegant way.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193