INVALID_ARGUMENT:每个请求最多允许 500 次写入 - Firebase Cloud Function - Firestore

Posted

技术标签:

【中文标题】INVALID_ARGUMENT:每个请求最多允许 500 次写入 - Firebase Cloud Function - Firestore【英文标题】:INVALID_ARGUMENT: maximum 500 writes allowed per request - Firebase Cloud Function - Firestore 【发布时间】:2020-05-07 19:34:18 【问题描述】:

我正在尝试在 Firebase Cloud Function 中运行以下代码。我要做的是遍历名为 savedData 的 Firestore 集合中的所有文档,解析每个文档中存储为字符串的 JSON,然后将解析后的数据存储到名为 stgPicks 的集合中的新文档中。 savedData 集合中的每个文档都应在 stgPicks 集合中创建 50-100 个新文档。

当我尝试运行该函数时,我收到以下错误代码。

谁能帮忙调试这段代码?我不确定我是否正确处理了批次。

Error: 3 INVALID_ARGUMENT: maximum 500 writes allowed per request
    at Object.callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:30:26)
    at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client.js:175:52)
    at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:341:141)
    at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:304:181)
    at Http2CallStream.outputStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:115:74)
    at Http2CallStream.maybeOutputStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:154:22)
    at Http2CallStream.endCall (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:140:18)
    at Http2CallStream.handleTrailers (/workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:265:14)
    at ClientHttp2Stream.emit (events.js:198:13)
    at ClientHttp2Stream.EventEmitter.emit (domain.js:466:23)
exports.parsePicksRecover = functions.https.onRequest((req, res) => 
  let savedDataRef = admin.firestore().collection('savedData')
  let allDrafts = savedDataRef
    .get()
    .then((snapshot) => 
      snapshot.forEach((doc) => 
        const docId = doc.id
        const getDoc = admin
          .firestore()
          .collection('savedData')
          .doc(`$docId`)
          .get()
          .then((doc) => 
            if (!doc.exists) 
              console.log('No matching document.')
             else 
              const response = doc.data().data_json.replace(`,]`, `]`).replace(`,`, ``)
              const data = JSON.parse(response)
              const draft = data.draft
              const draftId = draft.draftid
              const draftYear = docId.substring(0, 4)
              let paramsStatic = 
                draftid: draftId,
                datetime: draft.datetime,
                myteam: draft.myteam,
                user: draft.user,
                draftyear: draftYear
              

              const batchArray = []
              const batch = admin.firestore().batch()
              batchArray.push(batch)
              let operationCounter = 0
              let batchIndex = 0

              draft.picks.forEach((data) => 
                let paramsVar = 
                  teamid: data.teamid,
                  teamshortname: data.teamshortname,
                  fullname: data.fullname,
                  position: data.position,
                  school: data.school,
                  round: data.round,
                  ovrpick: data.ovrpick,
                  rdpick: data.rdpick,
                  createDate: admin.firestore.FieldValue.serverTimestamp()
                
                let params =  ...paramsStatic, ...paramsVar 

                let writeResult = admin
                  .firestore()
                  .collection('stgPicks')
                  .doc(`$draftYear|$draftId|$data.ovrpick`)
                batchArray[batchIndex].set(writeResult, params)
                operationCounter++
                if (operationCounter === 499) 
                  batchArray.push(firestore.batch())
                  batchIndex++
                  operationCounter = 0
                
              )

              batchArray.forEach(async (batch) => await batch.commit())
              return
            
          )
          .catch((err) => 
            console.log('Error getting document', err)
          )
      )
    )
    .catch((err) => 
      console.log('Error getting documents', err)
    )
)

Firebase Error Log

【问题讨论】:

【参考方案1】:

我在使用 php SDK 时确实遇到了同样的错误,在我的情况下,问题是在提交之后我需要创建一个 batch 的新实例,否则我认为它会尝试提交旧文档更改两次,这就是为什么您遇到每个请求允许的最大 500 次写入错误,例如:

let batch = admin.firestore().batch();

for (i = 1; i <= 10000; ++i) 
     // do something with the batch


     if (0 === i % 500) 
          batch.commit();
          batch = admin.firestore().batch();
     



batch.commit();

【讨论】:

以上是关于INVALID_ARGUMENT:每个请求最多允许 500 次写入 - Firebase Cloud Function - Firestore的主要内容,如果未能解决你的问题,请参考以下文章

云任务创建:错误:3 INVALID_ARGUMENT:请求包含无效参数

在 Jquery Validation 中最多允许 10 封电子邮件,每个逗号分隔

错误:(gcloud.app.deploy)INVALID_ARGUMENT:无法解析源

“在抛出 std::invalid_argument' what(): stoi 的实例后调用终止?”

我不断收到 'std::invalid_argument' what(): stoi 异常抛出似乎没有理由?

以 std::invalid_argument 类型的未捕获异常终止:stoi:无转换 (lldb)