Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - retrieve custom objects stored in a document in Cloud Firestore

I'm using Cloud Firestore as follows:

enter image description here

The collection 'events' holds documents that use unique event ID's as their names. In these documents are many 'EventComment' objects - each representing a comment made by a user.

To add the 'EventComment' object to the documents, I use the following:

EventComment mcomment = new EventComment();
mcomment.setComment("this is a comment");
Map<String, EventComment> eventMap = new HashMap<>();
eventMap.put(Long.toHexString(Double.doubleToLongBits(Math.random())), mcomment);

    firestore.collection("events").document(event_id)
            .set(eventMap, SetOptions.merge()).addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            Toast.makeText(EventCommentsActivity.this, "ya bastud", Toast.LENGTH_SHORT).show();
        }
});

I create a HashMap of String and my object 'EventComment' and then set this in the document.

However, when I want to retrieve all the 'EventComment' objects contained in a given document, I cannot cast it to an EventComment object, i.e. I cannot do this:

    DocumentReference docRef = db.collection("events").document("vvG17ZfcLFVna8");
docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        EventComment comment = documentSnapshot.toObject(EventComment.class);
    }
});

Also, trying to cast the documentSnapshot to a HashMap gives an 'unchecked cast' message and ultimately falls flat on its face. The idea is to use the comments to populate a RecyclerView.

I am thinking I may need to restructure the way I store the data?

Any suggestions would be greatly appreciated.

Cheers

like image 577
ZachOverflow Avatar asked Feb 22 '26 00:02

ZachOverflow


1 Answers

You are guessing right, you need to restructure the way you store the data. I'm saying that because the way you are storing the objects of typeEventComment in your actual database is not correct. As you can see in the official documentation regarding Quotas and Limits, the maximum size for a document is 1MiB. So if you continue to store the data like this, you'll reach the limit of 1MiB in a very short time.

Remember, Cloud Firestore is optimized for storing large collections of small documents. To solve this, I recommend you change the database structure like this:

Firestore-root
   |
   --- events (collection)
   |     |
   |     --- eventId (document)
   |     |     |
   |     |     --- //event details
   |     |
   |     --- eventId (document)
   |           |
   |           --- //event details
   |
   --- comments (collection)
         |
         --- eventId (document)
               |
               --- eventComments (collection)
                     |
                     --- eventCommentId (document)
                     |      |
                     |      --- //event comment details
                     |
                     --- eventCommentId (document)
                            |
                            --- //event comment details

As you can see, every obejct of type EventComment is added as a separate document within the events collection. In order to read the all the events objects, please use the following code:

DocumentReference docRef = db.collection("events");
docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        EventComment comment = documentSnapshot.toObject(EventComment.class);
    }
});

Edit:

If you want a list of commnets for a given eventId, please take a look again at the above database structure to see how it can be represented. And as you can you see, I have added a new collection named comments in which every new comment within a given eventId is also stored as a separate document. I came up with this structure to avoid nested maps.

If you are interested, you can take a look at one of my tutorials in which I have explained step by step, how to structure the database needed for the app.

like image 70
Alex Mamo Avatar answered Feb 23 '26 14:02

Alex Mamo