簡體   English   中英

返回值或 object 從 Firebase 雲 function 始終為 Z37A6259CC0C1DAE299A786648

[英]Returning value or object from Firebase cloud function is always null

我正在使用以下代碼從 Firebase 返回 object,但該值始終為 null。

這是我的 Firebase 雲 function:

exports.useVoucher = functions.https.onCall((data, context) => {
    const type = data.type
    const voucher_code = data.voucher_code
    const current_time = data.current_time
    console.log("useVoucher type is ", type + " and voucher_code is ", voucher_code)
    return admin.database().ref().child("vouchers").child(voucher_code).once("value").then((snapshot) => {
        if (snapshot.exists()) {
            console.log("useVoucher snapshot is ", snapshot.val());
            if (snapshot.val()[type] === true) {
                let path = "vouchers/" + voucher_code + "/" + type
                admin.database().ref().update({
                    [[path]]: current_time
                }, error => {
                    if (error) {
                        console.log("useVoucher failed")
                        return {is_valid: false}
                    } else {
                        console.log("useVoucher succeeded")
                        return {is_valid: true}
                    }
                })
            } else {
                console.log("useVoucher voucher found but type not found or not true")
                        return {is_valid: false}
            }
        } else {
            console.log("useVoucher voucher_code is not valid");
                        return {is_valid: false}
        }
    })
})

這就是我稱之為客戶端的方式(我刪除了一些不相關的代碼):

async function testVoucher(type) {
    const voucher_code = input_text.value.trim()
    console.log("submitVoucher voucher_code is ", voucher_code + " type is ", type)
    let current_time = Number(new Date())
    console.log("submitVoucher current_time is ", current_time)
    await useVoucher({ type: type, voucher_code: voucher_code, current_time: current_time })
        .then((res) => {
            console.log("submitVoucher res is ", res)
            let data = res.data
            console.log("submitVoucher data is ", data)
        })
        .catch((error) => {
            console.log("submitVoucher error is ", error)
        })
}

無論雲 function 采用哪條路徑,它總是返回“res is null”。 這是為什么?

您可以嘗試將雲 function 包裝在 promise 中,以在執行完成時返回解析回調並拒絕。

exports.useVoucher = functions.https.onCall((data, context) => {
    const type = data.type
    const voucher_code = data.voucher_code
    const current_time = data.current_time
    console.log("useVoucher type is ", type + " and voucher_code is ", voucher_code)
    return new Promise(function (resolve, reject) {
        admin.database().ref().child("vouchers").child(voucher_code).once("value").then((snapshot) => {
            if (snapshot.exists()) {
                console.log("useVoucher snapshot is ", snapshot.val());
                if (snapshot.val()[type] === true) {
                    let path = "vouchers/" + voucher_code + "/" + type
                    admin.database().ref().update({
                        [[path]]: current_time
                    }, error => {
                        if (error) {
                            console.log("useVoucher failed")
                            reject({ is_valid: false })
                        } else {
                            console.log("useVoucher succeeded")
                            resolve({ is_valid: true })
                        }
                    })
                } else {
                    console.log("useVoucher voucher found but type not found or not true")
                    reject({ is_valid: false })
                }
            } else {
                console.log("useVoucher voucher_code is not valid");
                reject({ is_valid: false })
            }
        })
    }
    
})

您的問題有兩個潛在原因:

  1. 你沒有鏈接承諾。 更准確地說,您不會返回admin.database().ref().update(...); . 你應該在這條線的前面有一個return
  2. 如果更新成功,您實際上不會返回任何內容。 事實上,即使在這一行前面添加return你也只會在出錯的情況下返回一些東西,而在成功的情況下什么也不返回: admin.database().ref().update({...}, error => { **You only return here**}) .

由於您使用了多個if塊,因此使用 async/await 更容易。 以下應該可以解決問題(未經測試):

exports.useVoucher = functions.https.onCall(async (data, context) => {   // See async keyword

    try {
        const type = data.type
        const voucher_code = data.voucher_code
        const current_time = data.current_time
        console.log("useVoucher type is ", type + " and voucher_code is ", voucher_code)

        const snapshot = await admin.database().ref().child("vouchers").child(voucher_code).get();
        if (snapshot.exists()) {
            console.log("useVoucher snapshot is ", snapshot.val());
            if (snapshot.val()[type] === true) {
                let path = "vouchers/" + voucher_code + "/" + type
                await admin.database().ref().update({
                    [[path]]: current_time
                });
                return { is_valid: true }
            } else {
                console.log("useVoucher voucher found but type not found or not true")
                return { is_valid: false }
            }
        } else {
            console.log("useVoucher voucher_code is not valid");
            return { is_valid: false }
        }
    } catch (error) {
        console.log(error);
        // Important: Look in the doc how to deal with an error in a Callable Cloud Function.
        //https://firebase.google.com/docs/functions/callable#handle_errors
    }

});

請注意,我們使用get()方法。 once("value")是正確的,但使用get()更清晰、更易讀( get()對於客戶端 SDK 還具有其他一些優勢,請參閱文檔)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM