谷歌云发布/订阅功能在查询 Firestore 时给出“请求的快照版本太旧”
Posted
技术标签:
【中文标题】谷歌云发布/订阅功能在查询 Firestore 时给出“请求的快照版本太旧”【英文标题】:Google cloud pub/sub function gives "The requested snapshot version is too old" when querying firestore 【发布时间】:2021-02-19 01:36:42 【问题描述】:我有一个对集合执行简单查询的 gcloud pub/sub 函数。它在 10 月 8 日之前运行良好。现在我看到“请求的快照版本太旧”错误消息。
我用相同的代码创建了一个 HTTP 函数并手动运行它,它工作得非常好。
函数如下:
// 0 3 * * * - at 03:00 AM every day
exports.GenerateRankings = functions.pubsub.schedule('0 3 * * *')
.onRun((context) =>
console.log("GenerateRankings Task started")
const playersCollection = admin.firestore().collection('players')
playersCollection.orderBy("Coin", "desc").get()
.then((qs) =>
console.log("Fetching Players by Coin")
// some staff
return true
)
.catch((error) =>
console.error("Error fetching players", error)
return false
)
)
这是错误堆栈:
9 FAILED_PRECONDITION: The requested snapshot version is too old.
at Object.callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client.js:327:49)
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:305:181)
at /workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:124:78
at processTicksAndRejections (internal/process/task_queues.js:79:11)
Caused by: Error
at Query._get (/workspace/node_modules/@google-cloud/firestore/build/src/reference.js:1466:23)
at Query.get (/workspace/node_modules/@google-cloud/firestore/build/src/reference.js:1455:21)
at /workspace/index.js:22:47
at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:130:23)
at /layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:198:28
at processTicksAndRejections (internal/process/task_queues.js:97:5)
code: 9,
details: 'The requested snapshot version is too old.',
metadata: Metadata internalRepr: Map , options:
我知道还有一个未回答的问题 "The requested snapshot version is too old." error in Firestore 类似于此。我正面临 pub/sub-functions 的这个问题。
感谢您的帮助。
【问题讨论】:
这是在每个函数触发器上发生还是偶发错误? 每次都会出现 我发现这个documentation 引用了这个错误并说if the backlog in the subscription is too old -- and the resulting snapshot would expire in less than 1 hour -- then FAILED_PRECONDITION is returned
。不确定它是否有帮助,但这是我找到的唯一一条相关信息。
我会说,您最好使用 Google 的 Issue Tracker 打开一个错误,以便他们能够解决您特定情况下发生的问题。
谢谢,@RafaelLemos。我已经解决了这个问题,请检查我的答案。
【参考方案1】:
如果有人遇到这个问题,我会回答我自己的问题。
经过大量阅读、测试后,我注意到我的日志中有一条警告,例如“函数返回未定义、预期的 Promise 或值”。因为我在函数中返回了一个承诺,所以我没有注意这一点。
在我的函数顶部添加一个 return 修复了我的警告,我的函数已经成功运行了 5 天。
return exports.GenerateRankings = functions.pubsub.schedule('0 3 * * *') ...
【讨论】:
【参考方案2】:我遇到了同样的问题,在我的情况下,代码如下并返回了这个问题中提到的错误。
const userSnapshots = await this.firestore.collection('Users').where('archive', '==', false).get();
const users = userSnapshots.docs
users.map(async (user) =>
//code to update user documents
);
然后我将代码更改为以下代码,并且没有返回此问题中提到的错误。
const userSnapshots = await this.firestore.collection('Users').where('archive', '==', false).get();
const users = userSnapshots.docs
const markPromises = users.map(async (user) =>
//code to update user documents
);
await Promise.all(markPromises);
我不知道这是这个问题的正确答案,但这对我有用。
【讨论】:
这解决了我的部分问题,请参阅我的回复。但经过较长时间后,我仍然会收到错误消息。【参考方案3】:我花了几个小时试图在“pubsub”中运行一系列操作,然后我决定尝试下面的代码,它成功了。
this.firestore.collection('Users').where('archive', '==', false).get().then(snap=>
// Code Here
);
【讨论】:
【参考方案4】:就我而言,我猜问题出在数据的大小以及进行数据管理所花费的时间上。我已将数据拆分为 5000 个元素的部分:
const store = getFirestore(initializeApp(myConfig));
const collectionRef = store.collection("users");
const limit = 5000;
let docs: Array<QueryDocumentSnapshot<DocumentData>>;
let querySnapshot: QuerySnapshot<DocumentData>;
let query = collectionRef.limit(limit);
do
querySnapshot = await query.get();
docs = querySnapshot.docs; // thanks to @prahack answer
for (const doc of docs)
await manageMyData(doc.id, doc.data());
if (docs.length > 0)
// Get the last visible document
query = collectionRef.startAfter(docs[docs.length - 1]).limit(limit);
while (docs.length > 0);
如果没有我的数据管理,我可以使用 10.000 个元素的一部分(限制 = 10000),但通过管理,我应该减少到 5000 个。
【讨论】:
以上是关于谷歌云发布/订阅功能在查询 Firestore 时给出“请求的快照版本太旧”的主要内容,如果未能解决你的问题,请参考以下文章
谷歌云 pubsub node.js 客户端与谷歌云功能不兼容
使用云功能在谷歌云发布/订阅上发布需要 3 分钟 - nodejs