简体   繁体   中英

Updating Firestore document with typescript map array type

I've created a map data type in Typescript react Example:

let employees = new Map<string, string>();
employees.set("name", "john");

and this is how I'm adding new values to firestore

const ref = firebase.firestore().collection("initialQuestions")
ref.doc('abc').set({ ??? })

The above method works only for a single value, how do I push the whole map at once to firestore?

Working with the JS web SDK, pure Javascript Objects are the only accepted type of data. This is shown in the SDK reference and the error message you would get by passing directly any other custom object that isn't a pure JS object:

“Error [FirebaseError]: Function DocumentReference.set() called with invalid data. Data must be an object, but it was: a custom Map object (found in document users/testUser1)”

Something the Firebase SDK makes available for this purpose is the FirestoreDataCoverter interface. This interface lets you create custom conversions from any data Class to a pure JS object. I created and tested the below code to convert a Map of Strings into Objects.

const firestoreDB = firebase.firestore();

let myMap = new Map<String, String>();
myMap.set("firstName", "Foo");
myMap.set("lastName", "Bar");

var mapConverter = {
  toFirestore: function(mapObj: Map<String, String>) { //toFirestore builds an Object which is returned and uploaded to Firestore
      return {
          firstName: mapObj.get("firstName"),
          lastName: mapObj.get("lastName"),
          };
  },
  fromFirestore: function(snapshot, options){ //fromFirestore is used to convert Objects fetched from Firestore to your custom Types
      const data = snapshot.data(options);
      return new Map<String, String>(Object.entries(data));
  }
};

firestoreDB.collection("users").doc("testUser1").withConverter(mapConverter).set(myMap) //using the converter, myMap can be passed directly
.then(() => {
  console.log("Document successfully written!");
})
.catch((error) => {
  console.error("Error writing document: ", error);
});

For your specific use case, the toFirestore() function will take your complete Map object and return a JS Object. Note that when I set my document, I append the withConverter(mapConverter) function. This function takes my converter implementation and uses it with the object I pass to the set() method, and no error is thrown by the SDK.

A simpler approach than this would be to use the Object.fromEntries(myMap) built-in function. This function would simply map everything into an Object. It worked on my tests, but it doesn't offer much customization as a FirestoreDataConverter does.

const firestoreDB = firebase.firestore();

let myMap = new Map<String, String>();
myMap.set("firstName", "Foo");
myMap.set("lastName", "Bars");

firestoreDB.collection("users").doc("testUser1").set(Object.fromEntries(myMap))
.then(() => {
  console.log("Document successfully written!");
})
.catch((error) => {
  console.error("Error writing document: ", error);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM