gpt4 book ai didi

firebase - 如何向数据库中的所有当前文档添加新字段?

转载 作者:行者123 更新时间:2023-12-04 23:45:00 24 4
gpt4 key购买 nike

所以我正在尝试为我的应用程序实现一个新的云功能,但它需要对我现有的数据库数据模型进行一些调整。我的数据库中的每个用户都有一个我每周都尝试更新的字段。我不希望此功能每周为所有用户运行,因为这将是一项不必要的昂贵操作。相反,我只是决定通过在他们的用户文档中存储一个“last-updated”字段来跟踪我上次更新该用户的时间。

问题是我现有的 400 多个用户都没有这个字段。所以我正在寻找一种方法来为数据库中的所有现有用户添加这个字段,启动到某个默认时间。

我考虑过使用此处描述的“批量写入”:
https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes

但似乎您需要指定要更新的每个文档的 ID。我的所有用户都有一个由 Firestore 生成的 UUID,因此我手动写入每个用户并不实际。有没有办法在现有集合的每个文档中创建一个新字段?或者,如果不是我获取所有文档 ID 列表的方法,以便我可以遍历它并进行非常难看的批量写入?我只需要进行一次大规模更新,然后再也不进行。除非我发现了我想跟踪的新数据。

最佳答案

您可以使用云函数:例如,您会在云函数的代码下方找到该代码,您可以通过在名为 batchUpdateTrigger 的集合中创建文档来触发该函数。 (请注意,这只是触发 Cloud Functions 的一种方式。您可以为此使用 HTTPS Cloud Functions)。

在此 Cloud Functions 函数中,我们获取名为 collection 的集合的所有文档。我们为它们每个添加一个带有当前日期/时间的新字段( ServerValue.TIMESTAMP )。我们使用 Promise.all()并行执行所有更新异步工作。不要忘记添加对 batchUpdateTrigger 的写访问权限集合并在云函数运行后删除它。

 exports.batchUpdate = functions.firestore
.document('batchUpdateTrigger/{triggerId}')
.onCreate((snap, context) => {

var collecRef = db.collection('collection');
return admin.collecRef.get()
.then(snapshot => {

const ts = admin.database.ServerValue.TIMESTAMP;
var promises = [];

snapshot.forEach(doc => {
const ref = doc.ref;

promises.push(
ref.update({
lastUpdate: ts
});
);

});

return Promise.all(promises);

});

});

您在这里可能会遇到的一个问题是您达到了 Cloud Function 的超时时间。默认超时为 60 秒,但您可以在 Google Cloud 控制台上增加它 ( https://console.cloud.google.com/functions/list?project=xxxxxxx )

另一种方法是,就像你说的,使用 批量写入 .

云函数将如下所示:
 exports.batchUpdate = functions.firestore
.document('batchUpdateTrigger/{triggerId}')
.onCreate((snap, context) => {

var collecRef = db.collection('collection');
return admin.collecRef.get()
.then(snapshot => {

const ts = admin.database.ServerValue.TIMESTAMP;
let batch = db.batch();

snapshot.forEach(doc => {
const ref = doc.ref;

batch.update(ref, {
lastUpdate: ts
});

});

return batch.commit();

});

});

但是,您需要在代码中管理批量操作 500 次的最大限制 .

下面是一种可能的简单方法(即不是很复杂......)。由于您将只设置一次默认值并且您只有几百个文档需要处理,我们可以认为它是可以接受的!以下 Cloud Function 将按 500 个批次处理文档。因此您可能需要手动重新触发它,直到处理完所有文档。
 exports.batchUpdate = functions.firestore
.document('batchUpdateTrigger/{triggerId}')
.onCreate((snap, context) => {

var collecRef = db.collection('collection');
return admin.collecRef.get()
.then(snapshot => {

const docRefsArray = [];
snapshot.forEach(doc => {
if (doc.data().lastUpdate == null) {
//We need to "treat" this doc
docRefsArray.push(doc.ref);
)
});

console.log("Nbr of doc to treat: " + docRefsArray.length); //When the output is 0 you are done, i.e. all the docs are treated

if (docRefsArray.length > 0) {

const ts = admin.database.ServerValue.TIMESTAMP;

let batch = db.batch();

if (docRefsArray.length < 500) {

//We can "treat" all the documents in the QuerySnapshot
docRefsArray.forEach(ref => {
batch.update(ref, {
lastUpdate: ts
});
});

} else {

//We need to "treat" only 500 documents
for (let i = 0; i < 500; i++) {
batch.update(docRefsArray[i], {
lastUpdate: ts
});
}

​return batch.commit();

} else {
return null;
}
});
});

最后一种技术的优点是,如果您遇到 Cloud Function 超时的一些问题,您可以减少批处理的大小。

关于firebase - 如何向数据库中的所有当前文档添加新字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54453776/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com