我有三个集合:“过去”,“今天”和“未来”。
“今天”集合应该只有一个文档。
在午夜时分,我需要在“未来”集合中找到一个包含“下一个”字段的文档,或者,如果没有这样的文档,请在“数字”字段中找到一个值比“我的“今天”收藏中的文档编号”字段。然后,我需要将“今天”的文档移至“过去”收藏夹,并将找到的文档从“未来”收藏夹移至“今天”收藏夹。
据我了解,没有“移动”方法,因此我必须使用删除和创建的组合,这需要在一个事务中完成。
我想出了如何执行“调度程序”部分,但无法弄清楚如何编写其余部分(文档的实际移动)。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const firestore = admin.firestore();
exports.scheduledFunction = functions.pubsub.schedule('0 0 * * *')
.onRun((context) => {
//I need to move my documents...
});
请帮我提供代码?
答案 0 :(得分:0)
可能是我在错误的位置寻找文档。它不在Firestore /具有云功能的扩展中。它在Firestore基本文档中,但是您必须将代码类型切换为node-js。 https://firebase.google.com/docs/firestore/query-data/order-limit-data
您必须通过两个查询来收集数据:今天和将来的集合。 通过这些查询,您可以获得文档及其数据。 比起您现在只需要制作文档,今天删除和新建文档(或重写现有文档)以及将来删除文档即可。
我可以通过一个简单的可调用函数来做到这一点:
exports.scheduledFunction = functions.pubsub.schedule('0 0 * * *')
.onRun(async (context) => {
try {
let queryToday = admin.firestore().collection('today'); //you can add .limit(1)
const todaySnapshot = await queryToday.get();
const todayDoc = todaySnapshot.docs[0];
const todayData = todayDoc.data();
const todayToPastRef = admin.firestore().doc(`past/${todayData.documentUid}`);
/* or how the id is stored? you can just call
const todayToPastRef = admin.firestore().collection('past').doc()
and it will be generated automatically
*/
const promises = [];
promises.push(todayToPastRef.set(todayData));
let queryFuture = admin.firestore().collection('future').orderBy('date').limit(1);
/*
or how is the date stored? Idk if firebase allows to query by Timestamp
you just want to fetch the closest date after today so the order is ascending
*/
const futureSnapshot = await queryFuture.get();
const futureDoc = futureSnapshot.docs[0];
const futureData = futureDoc.data();
const futureToTodayRef = admin.firestore().doc(`today/${futureData.documentUid}`);
promises.push(futureToTodayRef.set(todayData));
promises.push(futureDoc.ref.delete());
promises.push(todayDoc.ref.delete());
/*
or you can try to change today's doc data, but the id will remain the same
promises.push(todayDoc.ref.update(futureData))
*/
return Promise.all(promises); // function will be executed after all the promises are fullfilled or rejected
} catch (err) {
return Promise.reject(err);
}
});
请注意,不要使用async / await来代替.then()和.catch()。
使用console.log()进行调试,然后尝试使用VSCode,以便您可以检查对象上的方法和属性,这非常有帮助
更新: 是的,您可以批量进行。还有另一个例子:
exports.scheduledFunction = functions.pubsub.schedule('0 0 * * *').onRun((context) => {
const db = admin.firestore();
let queryToday = db.collection('today');
let queryFuture = db.collection('future').orderBy('date').limit(1);
const batch = db.batch();
return queryToday
.get()
.then(todaySnapshot => {
const todayDoc = todaySnapshot.docs[0];
const todayData = todayDoc.data();
const todayToPastRef = db.doc(`past/${todayData.docUid}`);
batch.set(todayToPastRef, todayData);
batch.delete(todayDoc.ref);
return queryFuture.get();
})
.then(futureSnapshot => {
const futureDoc = futureSnapshot.docs[0];
const futureData = futureDoc.data();
const futureToTodayRef = db.doc(`today/${futureData.docUid}`);
batch.set(futureToTodayRef, futureData);
batch.delete(futureDoc.ref);
// now two operations are completed, you just can commit the batch
return batch.commit();
})
.catch(err => {
// if todaySnapshot or futureSnapshot were not fetched, batch wont be commited
// or, for example, if snapshots were empty
return Promise.reject(err)
});
});
您还可以与.getAll()或类似的内容并行获取文档。您应该测试和尝试