【问题标题】:How to automatically update same field in different collections in Firestore如何自动更新 Firestore 中不同集合中的相同字段
【发布时间】:2020-10-23 08:08:53
【问题描述】:

我使用 Cloud Firestore 作为我的数据库,并且我有 users 的集合,其中存储了有关用户的基本信息,例如 ID、姓名、姓氏、电子邮件、公司 ID。

我还收集了companies,并且在每个公司中我都收集了tasks。 在每项任务中,我都从用户集合中分配了一个用户(复制了用户数据,因此该用户的数据与集合 users 中的数据相同)

问题是当我从集合 users 更新用户(更改名称或电子邮件...)时,因为数据被复制,该特定用户的 tasks 集合中的数据没有更改。

当集合users 中的用户更新为在tasks 集合中自动更新时,有什么方法可以使用firestore?

【问题讨论】:

    标签: firebase google-cloud-firestore


    【解决方案1】:

    这在 NoSQL 数据库中是一个相当标准的情况,我们经常对数据进行非规范化处理并需要保持这些数据同步

    基本上你有两种可能的主要方法:

    #1 来自客户端的更新

    当您更新“用户”文档时,同时更新包含用户详细信息的其他文档(即“任务”)。您应该使用batched write 来执行此操作:一批写入以原子方式完成,并且可以写入多个文档。

    大致如下:

    // Get a new write batch
    var batch = db.batch();
    
    var userRef = db.collection('users').doc('...');
    batch.update(userRef, {name: '....', foo: '....'});
    
    let userTaskRef = db.collection('companies').doc('...').collection('tasks').doc('taskId1');
    batch.update(userTaskRef, {name: '....'});
    
    userTaskRef = db.collection('companies').doc('...').collection('tasks').doc('taskId2');
    batch.update(userTaskRef, {name: '....'});
    
    // ...
    
    // Commit the batch
    batch.commit().then(function () {
        // ...
    });
    

    请注意,您需要知道哪些是“包含用户详细信息的其他(“任务”)文档:您可能需要进行查询以获取这些文档(及其DocumentReferences)。

    #2 通过云函数在后端更新

    编写并部署一个Cloud Function,当任何“用户”文档被更新时触发,它获取该“用户”文档的值并更新包含用户详细信息的“任务”文档。

    与第一种方法一样,在这种情况下,您还需要知道哪些是包含用户详细信息的“其他(“任务”)文档。

    根据您的评论(“是否有任何选项可以引用另一个表或放置外键?”)这里是一个云函数,它将更新所有(“任务”)文档DocumentReference 包含在“用户”文档中的专用数组字段 taskRefs 中。数组成员是data type 参考

    exports.updateUser = functions.firestore
        .document('users/{userId}')
        .onUpdate((change, context) => {
    
            const newValue = change.after.data();
    
            const name = newValue.name;
            const taskRefs = newValue.taskRefs;
            
            const promises = taskRefs.map(ref => { ref.update({ name: name, foo: "bar" }) });
            return Promise.all(promises);
    
        });
    

    您很可能会在前端的“用户”文档中设置taskRefs 字段的值。 JS SDK 的内容大致如下:

    const db = firebase.firestore();
    db.collection('users').doc('...').set({ 
       field1: "foo",
       field2: "bar",
       taskRefs: [   // < = This is an Array of References
           db.collection('tasks').doc('....'),
           db.collection('tasks').doc('....')] 
     });
    

    【讨论】:

    • 谢谢!是否有任何选项可以引用另一个表或放置伪造键?
    • 是的,您可以在用户文档中维护对任务文档的所有引用的列表。这将避免查询这些任务。但是请注意有一些limits to a Firestore doc,例如文档的最大大小 = 1 MiB,字段值的最大大小 = 1 MiB - 89 字节。
    • 您能否使用第三个选项更新您的答案,以便我们可以将所有内容集中在一个地方
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 2019-02-16
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多