Firebase Cloud Function(异步)未返回结果

时间:2019-04-10 11:39:22

标签: firebase google-cloud-firestore google-cloud-functions

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

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

我怀疑问题出在应付款被退回吗?根据此处的Firebase文档,尽管我不确定我在做什么完全正确https://firebase.google.com/docs/functions/callable

,异步可调用对象应返回Promise。

这是云功能的代码:

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)
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

不要合并Async/AwaitPromiseAsync本身就返回Promise

首先将云功能的返回值更改为:

return JSON.stringify(randomkeys);

还在writeKeyToDb中将更改返回到:

return key;

catch属于:

throw Error(error);

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

答案 1 :(得分:0)

最后找到了问题,感谢Doug和Dominik指导我朝正确的方向发展。我删除了promise,直接返回了值,但更重要的是,我不需要将数组转换为JSON。我遇到了HTTPSCallableResult documentation

我只是改变了这个

return JSON.stringify(randomkeys);

return randomkeys

并在客户端上,而不是

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

我愿意

if let keys = (result?.data as? NSArray) { dump(keys) }