Home > Blockchain >  Problem with the initial creation of a map structure within a document in firestore
Problem with the initial creation of a map structure within a document in firestore

Time:10-02

I have a small problem with the initial setup of my database.

My structure is this:

Database

I have an array of codes and a map that maps each code to an integer which will be updated.

Everything works as expected. I use the following code to achieve this goal. But there is exactly one problem: The very first writing to this document when it does not exist will not create a map of code: int but will create a field that has the name "comparisons.12345". So instead of a map, I end up with loads of individual fields (One for each code)

My workaround is to create the document manually with the empty map. After that everything works as expected

Of course, I could check on the frontend site if the document exists and add it if not. But this is a ONE-TIME operation. I do not want to pay for the overhead of checking the document EVERY TIME. So is there a way of creating it the correct way or do I have to stick to manual creating (Which is not a problem in production, but very annoying during testing)

val data = mutableMapOf(
            "codes" to FieldValue.arrayUnion(comp.getCode()),
            "comparisons."   comp.getCode() to FieldValue.increment(1)
        )

db.collection("codes").document("info").update(data as Map<String, Any>)

Update

When using set with merge set to true, the behavior is exactly the same when the document does not yet exist. Instead of the map I need, I get loads of documents with a "dot" in their name like this:

Unexpected result

CodePudding user response:

There are two ways in which you can update a document. The first one is when using DocumentReference#update(Map<String, Object> data) which:

Updates fields in the document referred to by this DocumentReference. If no document exists yet, the update will fail.

And the second one is when using DocumentReference#set(Object data, SetOptions options) which:

Writes to the document referred to by this DocumentReference. If the document does not yet exist, it will be created. If you pass SetOptions, the provided data can be merged into an existing document.

So there is no difference between using the update() and the set() method with the merge true option for documents that already exist. The difference between these two operations comes only for documents that don't exist. For instance, set() with the merge true option will create the document if the document does not exist, while when using the update(), the operation will fail.

So you should use the second option. In this way, you'll don't need to check the documents for existence.

Edit:

You're getting:

comparisons.12345

Because of the way you're trying to perform the update. To be able to perform an update to an element that exists within an object (map), you have to use another map:

val increment = mutableMapOf(
            comp.getCode() to FieldValue.increment(1)
        )
val data = mutableMapOf(
            "codes" to FieldValue.arrayUnion(comp.getCode()),
            "comparisons" to increment
        )
db.collection("codes").document("info").set(data, SetOptions.merge())

The above code will work only if comp.getCode() returns 12345.

  • Related