Https callable cloud function not returning value

守給你的承諾、 提交于 2019-12-02 16:19:40

问题


I have a Flutter app and I'm trying to get a client nonce from braintree. Per the braintree documentation, I have this in my cloud function:

exports.getClientNonce = functions.https.onCall(async (data, context) => {
    gateway.clientToken.generate({}, function (err, response) {
        if (err) {
            throw new functions.https.HttpsError('unknown', 'Error getting client nonce');
        } else {
            console.log(`token: ${response.clientToken}`);
            return response.clientToken;
        }
    });
});

Then, in my Flutter app I call the function (again, I'm following what the plugin says):

try {
    HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(
        functionName: 'getClientNonce',
    );

    dynamic result = await callable.call({});
    final value = result.data;  

    debugPrint('token: $value');

    var data = await BraintreePayment().showDropIn(
        nonce: value,
        amount: '2.0',
        enableGooglePay: false,
        inSandbox: true);
        print("Response of the payment $data");
    } on CloudFunctionsException catch (e) {
        debugPrint('An error occurred');
    } catch (e) {
        debugPrint('An error occurred');
    }
}

I tried changing the cloud function so that it only returns a random number (as soon as the function is executed), and my Flutter app is correctly receiving the value (so the cloud function is communicating fine). And in my Firebase console, I am able to view the client nonce specified by console.log. But the function is for whatever reason unable to return the actual client nonce. (It should be should be some string hash that is >2000 characters long)


回答1:


The callable function needs to return a promise from the top-level of the function callback that resolves with the value to return. Right now, you're returning nothing from the top-level. The return you have now is just returning a value from the inner callback function that you pass to braintree API. This isn't going to propagate to the top level.

What you need to do is either use a version of braintree API that returns an API (if one exists), or promisify the existing call that uses a callback.

See also "3. Node style callback" here: How do I convert an existing callback API to promises?

I have not tested this, but the general format if you apply that pattern will look more like this:

exports.getClientNonce = functions.https.onCall(async (data, context) => {
    return new Promise((resolve, reject) => {
        gateway.clientToken.generate({}, function (err, response) {
            if (err) {
                reject(new functions.https.HttpsError('unknown', 'Error getting client nonce'));
            } else {
                console.log(`token: ${response.clientToken}`);
                resolve(response.clientToken);
            }
        });
    });
});


来源:https://stackoverflow.com/questions/58262800/https-callable-cloud-function-not-returning-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!