首页 > 解决方案 > Firebase Cloud Function(异步)不返回结果

问题描述

我对 Firebase/Firestore/Cloud 函数相当陌生,并且一直在尝试一个小项目,其中客户端应用程序调用 Firebase Cloud Function 以生成一些随机密钥(随机数),将它们添加到 Firestore,并在成功编写后将这些密钥返回到客户端应用程序。有点像随机数生成器。

该函数由客户端正确调用(根据 Firebase 控制台),生成密钥,检查它们是否存在于 Firestore 中,如果不存在则添加它们。一切都在它应该将结果返回给客户端的部分工作。在这里,客户端永远不会得到结果(键数组)。事实上,客户端应用程序 (iOS/Swift) 中的回调永远不会被调用。

我怀疑问题在于承诺被退回?根据此处的 Firebase 文档,异步可调用对象应该返回一个 Promise,尽管我不完全确定我在做什么是正确的https://firebase.google.com/docs/functions/callable

下面是云函数的代码:

export const generateRandomKeys = functions.https.onCall(async (data, context) => {

  // Read data passed from client
  const numberOfKeys = data.numberOfKeys
  console.log("Number of keys to generate: ", numberOfKeys)

  // Generate some keys
  const generatedKeys = KeyMaker.newKeys(numberOfKeys)

  try {

    const randomkeys = []

    // Write keys to DB
    for (const key of generatedKeys) {
      const addedKey = await writeKeyToDB(key)
      randomkeys.push(addedKey)
    }

    return Promise.resolve(JSON.stringify(randomkeys))

  } catch (error) {
      console.log("Error has occured: ", error)
      throw new Error("An Error has occured: " + error)
  }
})


async function writeKeyToDB(key: string){

  try {
    // Check if a document with the same key already exists in the DB
    const docRef = db.collection("randomKeys").doc(key)
    const doc =  await docRef.get()

    // Document with same key found!
    if (doc.exists) {
      // Generate a new key and try again
      const newKey = KeyMaker.newKey()

      console.log("Will generate a new key and try again!. New key: ", newKey)
      await writeKeyToDB(newKey)
    }

    const keyDoc = {
      somefield: somevalue,     
    }

    // Write to DB then return result
    await docRef.set(keyDoc)

    return Promise.resolve(key)

  } catch (error) {
      return Promise.reject(error)
  }
}

客户端(斯威夫特)

     public static func generateNewRandomNumbers(numberOfKeys: Int) {

        FirebaseApp.configure()

        let functions = Functions.functions(region: FIRESTORE_REGION)

        functions.httpsCallable("generateRandomKeys").call(["numberOfKeys": numberOfKeys]) { (result, error) in

            // Nothing here executes                                                    
            print("----------got reply---------")
            if let error = error as NSError? {
                if error.domain == FunctionsErrorDomain {
                    let code = FunctionsErrorCode(rawValue: error.code)
                    let message = error.localizedDescription
                    print("Error \(String(describing: code)): " + message)
                }
            }

            if let keys = (result?.data as? [String]) {
                dump(keys)
            }
        }
    }

标签: firebasegoogle-cloud-firestoregoogle-cloud-functions

解决方案


不要结合Async/AwaitPromiseAsync作为自身返回Promise

首先将云函数的返回更改为:

return JSON.stringify(randomkeys);

writeKeyToDb可以更改返回:

return key;

catch部分:

throw Error(error);

我还看到在云函数中writeKeyToDb使用 2 个参数调用函数的问题,但该函数只有一个。但该代码可能正在进行中


推荐阅读