我对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)
}
}
}
答案 0 :(得分:1)
不要合并Async/Await
和Promise
。 Async
本身就返回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)
}