简体   繁体   English

使用 typescript map 数组类型更新 Firestore 文档

[英]Updating Firestore document with typescript map array type

I've created a map data type in Typescript react Example:我在 Typescript 反应示例中创建了一个 map 数据类型:

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

and this is how I'm adding new values to firestore这就是我为 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?上述方法仅适用于单个值,如何立即将整个 map 推送到 firestore?

Working with the JS web SDK, pure Javascript Objects are the only accepted type of data.使用 JS web SDK,纯 Javascript 对象是唯一接受的数据类型。 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:这显示在 SDK 参考和通过直接传递不是纯 JS object 的任何其他自定义 object 会得到的错误消息:

“Error [FirebaseError]: Function DocumentReference.set() called with invalid data. “错误 [FirebaseError]:Function DocumentReference.set() 使用无效数据调用。 Data must be an object, but it was: a custom Map object (found in document users/testUser1)”数据必须是 object,但它是:自定义 Map object(在文档 users/testUser1 中找到)”

Something the Firebase SDK makes available for this purpose is the FirestoreDataCoverter interface. Firebase SDK 为此目的提供的东西是FirestoreDataCoverter接口。 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.此接口允许您创建从任何数据 Class 到纯 JS object 的自定义转换。我创建并测试了以下代码以将 Map 的字符串转换为对象。

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.对于您的特定用例, withConverter(mapConverter) toFirestore() function将使您的完整Map 8828282995402888和返回a JS Object8888888888888888888888888888888888. object 我传递给set()方法,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.比这更简单的方法是使用Object.fromEntries(myMap)内置 function。这个 function 只是将 map 中的所有内容转换为 Object。它适用于我的测试,但它不像FirestoreDataConverter那样提供太多自定义

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);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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