pedaars
pedaars

Reputation: 161

Firestore adding hashmaps to a map field in Firestore

I am trying to create a map of objects in my firestore database using key->value pairs. The idea is to have a map of room objects within my Properties documents where living room would be the key and the object that value. Like the image below

rooms map

rooms map

I am getting lost with the correct way to add the objects into firestore as the rooms map is already there so how do I add a key->value pair into it ?? I also need to perform the search I have in the below code so I can grab the Properties document and add the objects into the room map field

FirebaseFirestore db = FirebaseFirestore.getInstance();
final CollectionReference propertyRef = db.collection("Properties");

final Room room = new Room(roomName, feet, inches, imageUrl);

propertyRef.whereEqualTo("propertyId", propertyId).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {

@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
     if (task.isSuccessful()) {
          for (QueryDocumentSnapshot doc : Objects.requireNonNull(task.getResult())) {
              propertyRef.document(doc.getId())
     ----->   .update("rooms", ""+roomName+"", room);

              Log.d(TAG, "Firebase Success= " + imageUrl);
              Toast.makeText(CreatePropertyActivity3.this, "Property Created", Toast.LENGTH_LONG).show();
              exProperties();
              }
              } else {
                  Toast.makeText(CreatePropertyActivity3.this, "Error check log", Toast.LENGTH_LONG).show();
     }
   }
 });

Upvotes: 3

Views: 8203

Answers (1)

Flavius P.
Flavius P.

Reputation: 547

Use the document(String) method on the db, which as per docs will create the document if it does not exist (https://firebase.google.com/docs/firestore/manage-data/add-data)

Map<String, Object> room = new HashMap<>();
room.put("feet", "...");
...

db.collection("rooms").document("the new room id")
        .set(room)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                  ...
            }
        })
        .addOnFalureListener(...)

This is if you know the IDs of your documents, or want to set the ID yourself. If so, you can replace the argument passed to .document(...) before adding a new item. Alternatively, you could use the add() method which will create a new document with an auto-generated ID for you.

In your case, it seems as though you are setting your own meaningful ids (e.g. livingroom, kitchen) and you should be changing the propertyId variable before adding a map. However, that is redundant since you already have an attribute (i.e. name) that describes the room. So use add() and avoid querying for a document that would not exist to begin with:

final HashMap<String, Object> newRoom = new HashMap<>();
newRoom.put(roomName, room);
...
propertyRef.add(newRoom)
    .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
        @Override
        public void onSuccess(DocumentReference documentReference) {
            Log.d(TAG, "DocumentSnapshot written with ID: " + documentReference.getId());
        }
    })
    .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.w(TAG, "Error adding document", e);
        }
    });

In fact, because you were using whereEqualTo you were always fetching a reference to the same document and overwriting its content. Just use the add() functionality and check the docs for more examples. Hope that helps!

Upvotes: 3

Related Questions