更新 Cloud Firestore 文档中的单个地图

use*_*026 8 javascript firebase google-cloud-firestore

最终更新 我从使用基于以下来自 andresmijares 的答案的事务更改为使用 set()。

这现在允许我将数据写入数据库。

var gradeDocRef = db.collection("students").doc(studentId);
                            console.log(gradeDocRef);

                            var setWithMerge = gradeDocRef.set({
                                "UnitGrades": {
                                            [unitNo]: {
                                                "CG": CG,
                                                "PG": PG, 
                                                "TG": TG
                                                }
                                            }
                                }, { merge: true });
Run Code Online (Sandbox Code Playgroud)

编辑 我根据下面来自 andresmijares 的评论更改了交易代码。

transaction.set(gradeDocRef, {merge: true}, {

但是然后得到这个错误?

传递给函数 Transaction.set() 的未知选项“UnitGrades”。可用选项:merge、mergeFields


我有一个包含学生集合的云 Firestore 数据库。每个学生集合都包含一个带有地图和子地图的学生文档,如下所示

UnitGrades: 
    {
     IT1:
       {                                  
        CG: "F"
        PG: "F"                                          
        TG: "F"
        id: "IT1"
        name: "Fundamentals of IT"
        type: "Exam"
    }
Run Code Online (Sandbox Code Playgroud)

我在地图中有 10 个单位 UnitGrades 每个学生都有相同的单位组合

我想根据 bootstrap 中的 HTML 表单更新地图(表单正在工作,加上很长,所以不要把它放在这里)

即改变学生成绩

我使用了 firestore 事务更新文档,并稍作调整以从 HTML 表单中获取数据。

let studentId = $(this).attr("data-student-id");
let unitNo = $(this).attr("data-unit");
let CG = $(this).attr("data-CG");
let PG = $(this).attr("data-PG");
let TG = $(this).attr("data-TG");

// Create a reference to the student doc.
var gradeDocRef = db.collection("students").doc(studentId);
console.log(gradeDocRef);
    return db.runTransaction(function(transaction) {
// This code may get re-run multiple times if there are conflicts.
    return transaction.get(gradeDocRef).then(function(gradeDoc) {

   if (!gradeDoc.exists) {
     throw "Document does not exist!";
}

// update the grades using a transaction

   transaction.update(gradeDocRef, {

// in here is my error, I need to be able to select the map
// for the variable for UnitNo only and not wipe the other maps

    "UnitGrades": {

    [unitNo]: {

    "CG": CG,

    "PG": PG, 

    "TG": TG                                                }
});
});

}).then(function() {

console.log("Transaction successfully committed!");

}).catch(function(error) {

console.log("Transaction failed: ", error);
console.log(studentId);

});
Run Code Online (Sandbox Code Playgroud)

我实现的代码更新了正确的单位映射,但随后擦除了其余的 UnitGrades。我真正想要的是更新变量中标识的单位图

UnitNo 然后保持其余的单位不变。

例如,目前如果我更新 IT1,这会正确更新地图中的等级,但随后会从 UnitGrades 地图中擦除单元 IT2、IT3、IT12 等。我真的希望 IT2、IT3、IT12 等保持原样,并且 IT1 使用新值进行更新。例如“F”变成“P”

and*_*res 21

更改这些行:

transaction.update(gradeDocRef, {
    "UnitGrades": {
    [unitNo]: {
       "CG": CG,
       "PG": PG, 
       "TG": TG                                                }
});
Run Code Online (Sandbox Code Playgroud)

为了这

transaction.set(gradeDocRef, {
    `UnitGrades.${unitNo}`: {
       "CG": CG,
       "PG": PG, 
       "TG": TG 
}, { merge: true });

Run Code Online (Sandbox Code Playgroud)

据我所知,它是这样工作的:

假设你的文档看起来像这样:

 {
   "fantasticsFours": {
     "thing": { ... },
     "susan": { ... },
     "mister": { ... }
   }
 }
Run Code Online (Sandbox Code Playgroud)

我们需要添加 {"humanTorch" :{...}}

设置+合并

db.collection('heroes').doc(`xxxXXXxxx`).set({
  "fantasticsFours": {
    "humanTorch":{ ... }
  }
}, {merge:true})
Run Code Online (Sandbox Code Playgroud)

将导致此数据:

 {
   "fantasticsFours": {
     "thing": { ... },
     "susan": { ... },
     "mister": { ... },
     "humanTorch":{ ... }
   }
 }
Run Code Online (Sandbox Code Playgroud)

有更新

db.collection('heroes').doc(`xxxXXXxxx`).update({
  "fantasticsFours": {
    "humanTorch":{ ... }
  }
})
Run Code Online (Sandbox Code Playgroud)

将导致此数据:

 {
   "fantasticsFours": {
     "humanTorch":{ ... }
   }
 }
Run Code Online (Sandbox Code Playgroud)

更多在这里