【问题标题】:Adding a Firestore document as part of a document update添加 Firestore 文档作为文档更新的一部分
【发布时间】:2019-09-01 05:18:06
【问题描述】:

我希望能够在一个集合中创建一个新文档,作为更新另一个集合中文档的一部分。

简单版。用户通过单击按钮更新任务的状态。

我需要做的是这个

completeTask(task:ITask) : Promise<any>
{
  const userId = this.auth.userId;

  this.afs.collection('Tasks').doc(task.id).update({Status: 'COMPLETE'});
  this.afs.collection('Notifications').add({Task:task.id, Status: 'COMPLETE', UserId: userId});
  // ...
  // return Promise here;
}

以上需要作为单个操作的一部分发生。 我已经阅读了所有关于批处理和事务的内容,但似乎无法找到如何正确执行此操作。 我可以按顺序运行它们并返回一个

Promise.all(taskPromise, notifyPromise);

或将一个链接在一起 - 但我希望有一个更优雅的解决方案。

【问题讨论】:

    标签: angular collections transactions google-cloud-firestore


    【解决方案1】:

    如果您希望两个写入作为一个操作发生(要么都成功,要么都不发生),您应该use a batched write or transaction。 Promise 是一种客户端机制,因此不是实现原子性的理想方式。

    【讨论】:

    • 我想使用其中任何一个,但我找不到任何演示如何创建新文档的示例。 Batch 示例都展示了如何更新多个文档。我想更新一个并创建另一个 - 寻找一个关于如何做到这一点的具体示例(工作代码)。
    • firebase.google.com/docs/reference/js/…firebase.google.com/docs/reference/js/… 都包含在他们的文档中:“写入由提供的 DocumentReference 引用的文档。如果该文档尚不存在,它将被创建。 "
    • 我知道这些——我的问题是关于它如何工作的示例代码,因为当我按照文档进行操作时会出现错误。当我获得对各个位置的引用以在我的服务中更新和设置和使用它们时,我收到错误 'AngularFirestoreDocument' 类型的参数不可分配给'DocumentReference' 类型的参数 .因此我要求工作代码。
    【解决方案2】:

    我找到了我正在寻找的答案。 将文档作为批处理的一部分创建的问题是您必须生成自己的密钥 - 使用您管理的密钥或从 Firestore 获取的密钥。事后看来,这很明显,因为批处理需要在给定的文档上工作 - 我因普通参考上的 .add() 会添加你的新文档并给它一个 ID 而分心 - 我正在寻找一种方法使用批处理执行此操作。

    这是我最终使用的代码

    @Injectable({
      providedIn: 'root'
    })
    export class ProjectService {
      // AuthService is implied but not shown as part of this example
      constructor(private afs: AngularFirestore, private auth:AuthService) { }
    
      // Update Project and write an event log to the projects ActivityLog
      // as part of the same write
      UpdateProject(projectName: string, data:any) : Promise<void>
      {
        // Get a batch reference
        const batch = this.afs.firestore.batch();
    
        // Reference to the Project document that needs to be updated
        const ref = this.afs.collection('Projects').doc(projectName);
    
        // Get a unique Firestore ID for the ActivityLog document
        const newLogId = this.afs.createId();
    
        // Reference to the ActivityLog doc using the ref and ID created above
        const logref = ref.collection('ActivityLog').doc(newLogId);
        batch.update(ref.ref, data);
    
        // Create the new entry
        batch.set(logref.ref, {
          Created: firestore.FieldValue.serverTimestamp(), 
          User: this.auth.UserName,
          Action: 'Update', 
          Data: JSON.stringify(data)
        });
    
        return batch.commit();
      }
    }
    

    在我的组件中

    onUpdate(data:any) {
      this.projectSvc.UpdateProject(this.projectName, data)
        .then(() => alert('Update successful'));
    }
    

    关键位是生成 Id 并在对新 ActivityLog(在本例中)文档的引用中使用它。

    侧边栏:这可能是作为云函数完成的 - 我们甚至正在研究这个的原因是我们需要知道进行更改的用户,并且根据完成的研究,您无法获得触发 Firestore 更改的用户(我相信您可以实时)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-14
      • 2018-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多