Firebase 如何在Firestore中自动更新不同集合中的相同字段

Firebase 如何在Firestore中自动更新不同集合中的相同字段,firebase,google-cloud-firestore,Firebase,Google Cloud Firestore,我使用Cloud Firestore作为我的数据库,我收集了用户,其中存储了有关用户的基本信息,如id、姓名、姓氏、电子邮件、公司id 我还收集了公司,每个公司都收集了任务。 在每个任务中,我从用户集合中分配了一个用户(用户数据被复制,因此该用户的数据与集合users中的数据相同) 问题是当我从集合用户更新用户(更改名称或电子邮件…)时,因为数据是复制的,所以该特定用户的任务集合中的数据不会更改 当集合用户中的用户被更新时,是否有任何方法可以使用firestore在任务集合中自动更新它?这在No

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

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

问题是当我从集合
用户
更新用户(更改名称或电子邮件…)时,因为数据是复制的,所以该特定用户的
任务
集合中的数据不会更改


当集合
用户
中的用户被更新时,是否有任何方法可以使用firestore在
任务
集合中自动更新它?

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

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

    });
基本上有两种可能的主要方法:

#1来自客户端的更新 更新“用户”文档时,同时更新包含用户详细信息的其他文档(即“任务”)。您应该使用a来完成这一操作:一批写入操作以原子方式完成,并且可以写入多个文档

大致如下:

// 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 () {
    // ...
});

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

#2通过云功能在后端进行更新 编写并部署一个在任何“用户”文档更新时触发的,并获取此“用户”文档的值,并更新包含用户详细信息的“任务”文档

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

在您的评论之后(“是否有任何引用其他表或放置外键的选项?”)这里有一个云函数,它将更新所有的(“任务”)文档,这些文档的
DocumentReference
包含在“用户”对话框中的专用数组字段
taskRefs
中“医生。数组成员为参考

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('....')] 
 });
const db=firebase.firestore();
db.collection('users').doc('…').set({
字段1:“foo”,
字段2:“酒吧”,
taskRefs:[/<=这是一个引用数组
db.collection('tasks').doc('..'),
db.collection('tasks').doc('..')]
});

谢谢!是否有引用其他表或输入键的选项?是的,您可以在用户文档中维护对任务文档的所有引用的列表。这将避免查询这些任务。不过,请注意有一些选项,例如,文档的最大大小=1 MiB,字段值的最大大小=1 MiB-89字节。请使用第三个选项更新您的答案,这样我们就可以将所有内容放在一个地方了