更新多个火石集合

时间:2021-04-09 02:58:16

标签: reactjs firebase google-cloud-firestore

所以我正在尝试更新 2 个 Firebase 集合,这些集合将包含一个相同的数组元素。 例如,我正在构建一个作业应用程序,因此当用户创建作业时,它会将作业对象推送到名为 alljobs 的 firebase 集合中,该集合位于名为 alljobs 的文档下。此外,同一个作业会被推送到名为 created jobs 的 firebase 集合。应用程序上的每个用户都有自己创建的作业,每个文档都被命名为用户 ID。 是否有一种简单的方法可以在 alljobs 集合和 createdjobs 集合中更新此特定作业? 例如,我这样做的方法是这样的。

Individual Job component (obtained by previously mapping through all the jobs)

const [userjobs, setUserjobs] = useState([])
const {job, createdjobs} = props
function updateJob(){
   createdjobs?.map(job1=>{
     if(job1.jobid===job.jobid){
      const jobindex = createdjobs.indexOf(job1)
      
      createdjobs[jobindex].jobtitle = 'New title'
      
      db.collection('createdjobs').doc(user.uid).update({
        jobs: createdjobs
      })
   }
  })
}

*我基本上必须重复同样的过程来再次更新 createdjobs 集合中刚刚更新的作业。这会变得重复和混乱。所以正在寻找解决方案。这次通过所有作业进行映射。

 useEffect(()=>{

  db.collection('alljobs').doc('alljobs').onSnapshot(snap=>{
    setAlljobs(snap.data().jobs)
  })

},[])

3 个答案:

答案 0 :(得分:0)

我认为您的问题没有捷径可走。但我建议您为 Firebase 函数编写一个同步函数。 它将监视一个源的变化并同步到其他源。这样您的逻辑代码只需要管理一个信任源。

答案 1 :(得分:0)

正如@Thanh Le 建议的那样,您可以编写一个 Google Cloud Function 来实现此目的。在云函数中,有一个名为触发器的函数类型。您可以使用此触发器。

云函数触发器

我们可以编写函数,当指定的文档或文档集出现时会自动触发,

  1. onCreate - 创建文档时触发
  2. onUpdate - 当文档已经存在并且有任何值更改时触发。
  3. onDelete - 文档删除时触发
  4. onWrite - 当 onCreateonUpdateonDelete 被触发时触发。

从这些触发器中,您可以使用 onWrite 触发器来实现该功能。

exports.updateAllJobsTrigger = functions.firestore.document('createdJob/{userId}')
    onWrite(async (change, context) => {
        // Check if document is deleted
        if (!change.after.exists) {
            logger.log('Document not existing. Function exited.');
            return;
        }

        const allJobsRef = admin.firestore().collection('alljobs').doc('alljobs');
        
        // Check if document created
        if (!change.before.exists) {
            try {
                // This is a newly created document. Therefore newjob should be in first element
                const newJob = change.after.data().jobs[0];
                const data = (await allJobsRef.get()).data();
                if (data) {
                    const jobs = data.jobs;
                    await allJobsRef.update({
                        jobs: [...jobs, newJob]
                    });
                    logger.info('Job added to All jobs queue.');
                }
            } catch (exception) {
                logger.error(exception)
            }

            return;
        }

        
        try {
            // This is a updating document.newly added job is in the last element of the array
            const newJob = change.after.data().jobs[change.after.data().jobs.length - 1];
            const data = (await allJobsRef.get()).data();
            if (data) {
                const jobs = data.jobs;
                await allJobsRef.update({
                    jobs: [...jobs, newJob]
                });
                logger.info('Job added to All jobs queue.');
            }
        } catch (exception) {
            logger.error(exception)
        }
    });

答案 2 :(得分:0)

正如@Nimna Perera 所说,您可以使用 Cloud Functions 来解决此问题。当文档被更新、创建或删除(所以 onWrite 选项)时,你的 CF 应该被触发。另一种方法是通过 transactions,当您需要读取和写入文档或 batched writes,当您只需要写入一个或多个文档时。在这两种情况下,您都不受限于单个集合,因此它应该可以解决您的问题。

相关问题