Firestore导出数据到GCS时接口提前返回导致文件不存在如何解决
Firestore导出GCS提前返回导致后续文件访问失败的解决方案
你调用的client.exportDocuments方法默认仅返回任务创建成功的响应,而非导出完成的结果,导出任务是后台异步执行的,所以你拿到响应立刻去访问文件会触发不存在的报错,可根据场景选择以下解决方案:
方案1:等待导出任务完全完成(适用于中小数据量,导出耗时<9分钟的场景)
Firestore Admin SDK返回的导出结果是长时运行Operation对象,内置promise()方法,可直接等待该方法返回再执行后续导入逻辑,修改后的代码如下:
const functions = require('firebase-functions'); const firestore = require('@google-cloud/firestore'); const client = new firestore.v1.FirestoreAdminClient(); const bucket = 'gs://BUCKET_NAME'; exports.scheduledFirestoreExport = functions.pubsub.schedule('every 24 hours').onRun(async() => { const projectId = process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT; const databaseName = client.databasePath(projectId, '(default)'); // exportDocuments返回数组的第一个元素为Operation对象 const [operation] = await client.exportDocuments({ name: databaseName, outputUriPrefix: bucket, collectionIds: [], }); // 等待导出任务完全执行完成后再往下走 const [response] = await operation.promise(); console.log(`Backup Successful,输出路径:${response.outputUriPrefix}`); // 此处再执行BigQuery导入逻辑即可 });
方案2:事件驱动触发导入(适用于大数据量,导出耗时超过云函数最长9分钟超时限制的场景)
- 拆分导出、导入为两个独立云函数,定时函数仅负责触发导出任务,不等待任务完成
- 新增一个GCS对象创建事件触发的云函数,Firestore导出完成后会自动在输出路径生成名为
overall_export_metadata的元数据文件,监听到该文件创建后再触发BigQuery导入逻辑,完全规避提前访问的问题
方案3:兜底容错校验
不管用上述哪种方案,都可以在执行导入前增加前置校验,调用GCS SDK的file.exists()方法确认目标导出文件/元数据文件已存在,再执行后续导入操作,进一步降低报错概率。
内容的提问来源于stack exchange,提问作者secret
相关产品推荐
相关产品推荐

