Firebase Doc 的 ARRAY 字段在插入时为空

Firebase Doc's ARRAY field is empty upon insert

我有一个非常简单的流程,它获取(列出)所有员工,然后循环他们并在循环每个用户后插入另一个 firebase 文档

  async insertAchivementTest() {
    let eeRef = this.afStore.collection<any>(`.../EmpSnapshot`).ref
    let eeDoc: any = eeRef
    eeDoc = eeDoc.where("employment.event", "not-in", ["TER", "RSG"])  // only active staff

    await eeDoc.get().then(async res => {
      for (let ee of res.docs) {            // loop active EE
        console.log(`proc ee = ${ee.id}`)

        // each emp, loop find evaluators
        let eeEvaluators = [] // array of object

        let formEvaluators = [{ type: 'BY_ROLE', role: '_DIRECT_REPORT_' }]
        formEvaluators.forEach(async ev => {
          await this.afStore.doc<any>(`...udion.com`).ref.get().then(res => {
            eeEvaluators.push(res.data())
          })
        })
        let achievementData = {
          email: ee.id,
        //   evaluators: ['A', 'B'],
          evaluators: eeEvaluators,
        }
        console.log('show achievement before insert...=', achievementData)
        await this.afStore.collection(`.../Collection/Achievements`)
          .ref
          .add(achievementData)
      }
    })
  }

为了确保获取正确的数据并将其插入到新文档中,我 console.log 在将它们作为 firebase 文档插入之前(查看下面的控制台日志屏幕截图) ARRAY 变量 eeEvaluators 是一个对象数组,它包含一个字段 'evaluators',其值显示在控制台日志中。但是为什么每次它试图通过 .add(...) 存储到 firebase doc 时,字段 'evaluators' 总是一个空数组?

注意: 我正在使用 angularfire 包

// Firebase package
import {
    AngularFirestore,
    AngularFirestoreCollection
} from "@angular/fire/firestore";
import { AngularFireStorage } from "@angular/fire/storage";

5 月 20 日上午 8 点更新: 我发现了奇怪的行为,如果我从循环中移出检索逻辑,它确实会正确插入到文档中。在循环逻辑中找不到任何怪人。此外,如您所见,循环是 jz LOOP-ONCE 逻辑。我 PRETTY-MUCH 确认了由循环引起的奇怪行为,但我必须有一个循环来支持我的业务逻辑。

        // let formEvaluators = [{ type: 'BY_ROLE', role: '_DIRECT_REPORT_' }]
        // formEvaluators.forEach(async ev => {
        //     await this.afStore.doc<any>(`...udion.com`).ref.get().then(resUser => {
        //         eeEvaluators.push(resUser.data())
        //     })
        // })

        // CHANGE TO following code (no loop)
        await this.afStore.doc<any>(`...udion.com`).ref.get().then(resUser => {
                eeEvaluators.push(resUser.data())
            })

更新 20 May 1140AM:我在这里找到了解释,forEach 在 async/await、 上效果不佳 所以我更换了

formEvaluators.forEach(async ev => {

for (const ev of formEvaluators) 

在我的代码中,它可以正常工作!

那是因为你的嵌套数据太多了。 Firebase 不以您想要使用它的方式直接支持数组。您可以将其存储为地图,但我建议您创建一个新的子集合,然后存储这些值。在这种情况下,如果你有这样的结构,如果你想将它们应用到 f​​irebase,你必须在根上使用子集合或普通集合。 Firebase 并非旨在描述数据,例如您准备数据的方式。创建一个带有“评估器”的子集合,并尽可能保持保存在那里的数据。 您的数据结构的另一件事是您无法更新它们。如果你想更新“评估者”中的单个字段,你不能这样做。您必须更新“评估者”字段的完整树结构。但是,如果您使用集合/子集合,您可以比保存在单个字段中的嵌套地图更好地管理更新、插入和删除。

我在这里找到了解释,forEach 不适用于 async/await, 所以我替换了

formEvaluators.forEach(async ev => {

for (const ev of formEvaluators) 

在我的代码中,它运行正常!