javascript Map to Firestore -> Error: Value for argument "data" is not a valid Firestore document. Input is not a plain JavaScript obj

Viewed 1605

trying to set map variable value in javascript to firestore document as map field using cloud function. It fails with error - Error: Value for argument "data" is not a valid Firestore document. Input is not a plain JavaScript object (found in field.
map_field: myMap is causing the problem. So how do I set javascript map as map field in firestore document?

admin.firestore().collection("users").doc("test").set({
                                          name: "Los Angeles",
                                          state: "CA",
                                          map_field: myMap // map variable
                                      })

Full Code here: I am aggregating data from multiple firestore documents and trying to insert into a new document.

Code------------------------->

exports.fxname= functions.https.onRequest((request, response) => {
 collectionRef = admin.firestore().collection('user/doccx/collx');

let myMap = new Map();

collectionRef.listDocuments().then(documentRefs => {
                          console.log('Fetching each document:console log');
                          return  admin.firestore().getAll(...documentRefs)
                          .then(documentSnapshots => {
                                for (let documentSnapshot of documentSnapshots) {
                                 let name = documentSnapshot.get('aa');
                                 let totalScore= documentSnapshot.get('bb');
                                
                                 myMap.set(name, totalScore.toString());
                                }
                                functions.logger.log("calculation done: ");
                                console.log(Array.from(myMap) ); //prints values
                                var keys = Object.keys(myMap);
                                keys.forEach(key=>{
                                  console.log(key + '|' + myMap[key]); //this is not printing any value
                                });

                                 admin.firestore().collection("users").doc("test").set({
                                          name: "Los Angeles",
                                          state: "CA",
                                          country: myMap
                                      }).then(function() {
                                           functions.logger.info("Insert Successful !", {structuredData: true});
                                            return;
                                        })
                                        .catch(function(error) {
                                            functions.logger.error("Error writing document: ", error);
                                        });


                                return;
                           }).catch(function(error) {
                              functions.logger.error("Error 1: ", error);
                              });
                       }).catch(function(error) {
                             functions.logger.error("Error 2: ", error);
                           });
 response.send("Hello from Firebase Outside!");`enter code here`

});

Unrelated with the issue but also getting below warning. It has to do with nesting of .then. any suggestion on rewriting above code?

108:34 warning Avoid nesting promises promise/no-nesting

108:34 warning Avoid nesting promises promise/no-nesting

2 Answers

Like the error message dictates, you are not allowed to insert maps into the database. A workaround is to just convert this into a JSON object like so:

let myMap = {};
myMap[name] = totalScore.toString();

That should fix the problem.

108:34 warning Avoid nesting promises promise/no-nesting

This is a result from ESLINT being set up to avoid promise nesting. I do not know the potential issues in the functional results but it does make understanding the code a lot harder and potentially prolong the runtime of the code when it is nested deeply. You can use the javascript async await functions to remove the need to nest said promises.

JS maps are not supported in firestore. use normal JS objects and insert them in your database like:

let contact = {'Jessie':{phone: "213-555-1234", address: "123 N 1st Ave"}}

// example overwrite a doc in firestore
db.collection("contacts").doc('test').set(contact)

check here for all supported data types

Related