Google Pub / Sub更新Firestore子集合

时间:2019-12-02 15:36:38

标签: javascript firebase google-cloud-firestore google-cloud-functions google-cloud-pubsub

我试图每2分钟更新一次子集合中的字段。如果时间戳早于3分钟,我会将字段“状态”更改为“关”。我有一个有人帮助我的代码,它可以与集合一起使用,但是我不知道该使用哪个集合路径来访问其中包含此子集合的所有文档。

5分钟后,如果时间戳超过3分钟,我希望“状态”字段为“关闭”。

const snap =等待db.collection(“ MX”)有效,但仅适用于1层深度。 userProfiles中的每个文档都有MX的子集合。

我尝试了通配符和几种不同的收集路径。

enter image description here

enter image description here

exports.updateIdle = functions.pubsub.schedule('every 2 minutes').onRun(async () => {

const db = admin.firestore();
// this is what line I am trying to figure out
  const snap = await db.collection("userProfiles") 
    .where("Status", "=", "On")
    .where("Timestamp", "<", admin.firestore.Timestamp.fromMillis(Date.now() - 3 * 60000))
    .get();


  await Promise.all(snap.docs.map(doc => doc.ref.update({Status: 'Off'})));

  console.log('this goes off every two minutes')
}); 

编辑: userProfile->每个文档-> 4个子集合(MX,员工,设置,日志)

我的文档存储在MX中。这些文档将具有状态和时间戳。

我希望此发布/订阅检查存储在MX子集合内的所有文档。

如果时间戳是3-5分钟,并且Status = On。我想将状态更改为关闭

因此,我正在检查所有MX子集合。在这种情况下,userProfiles中有4个文档,并且每个文档中都有一个MX子集合。

我非常感谢您的帮助。我希望我已经解释得足够好了。谢谢。

1 个答案:

答案 0 :(得分:1)

如果您要“更新具有旧时间戳的任何MX子集合中的所有文档”,则应该使用Promise.all()

exports.updateIdle = functions.pubsub.schedule('every 2 minutes').onRun(async () => {

    const db = admin.firestore();

    const querySnapshot = await db.collection("userProfiles") 
        .where("Status", "=", "On")
        .where("Timestamp", "<", admin.firestore.Timestamp.fromMillis(Date.now() - 3 * 60000))
        .get();

    const promises = [];
    querySnapshot.forEach(doc => {
        const docRef = doc.ref;
        promises.push(docRef.collection('MX').get());
    });

    const snapshotArrays = await Promise.all(promises);
    // snapshotArrays contains an array of arrays of QueryDocumentSnapshots

    const promises1 = [];

    snapshotArrays.forEach(snapArray => {
        snapArray.forEach(snap => {
            promises1.push(snap.ref.update({
                Status: "Off"
            }))
        })
    });

    return Promise.all(promises1);

});

当然,我假设您的初始查询是找到具有“ userProfile旧”字词的timestamp文档。


根据您的评论进行更新

我了解,“时间戳记的使用时间为3-5分钟,并且Status = On”的过滤是在MX文档级别进行的。然后,下面的命令应该起作用(我们将where子句移到MX集合中)。但是请注意,在这种情况下,我们将读取所有userProfile个文档(每次读取都会消耗一个标准文档)。

exports.updateIdle = functions.pubsub.schedule('every 2 minutes').onRun(async () => {

    const db = admin.firestore();

    const querySnapshot = await db.collection("userProfiles").get();

    const promises = [];
    querySnapshot.forEach(doc => {
        const docRef = doc.ref;
        promises.push(docRef.collection('MX').where("Status", "=", "On")
        .where("Timestamp", "<", admin.firestore.Timestamp.fromMillis(Date.now() - 3 * 60000)).get());
    });

    const snapshotArrays = await Promise.all(promises);
    // snapshotArrays contains an array of arrays of QueryDocumentSnapshots

    const promises1 = [];

    snapshotArrays.forEach(snapArray => {
        snapArray.forEach(snap => {
            promises1.push(snap.ref.update({
                Status: "Off"
            }))
        })
    });

    return Promise.all(promises1);

});

如果仍然遇到错误,请尝试不使用where子句,如下所示,并引用where子句以获取所需的MX文档选择。

//....
const querySnapshot = await db.collection("userProfiles").get();

const promises = [];
querySnapshot.forEach(doc => {
    const docRef = doc.ref;
    promises.push(docRef.collection('MX').get());
});
//....