从 Firebase 函数返回数据到 Android [英] Return data to Android from Firebase Function

查看:20
本文介绍了从 Firebase 函数返回数据到 Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试做的事情:只需从 Firebase Cloud Function 返回数据.

What I am trying to do: Simply return data from Firebase Cloud Function.

该函数用于在支付网关的服务器中创建支付订单.

The function is used to create a payment order in the payment gateway's server.

function(err,data)(见下文)中提供了有关订单详细信息的所需数据,但我需要将此数据发送回我的 Android 应用程序.

My required data about the order's details are present in the function(err,data) (see below), but I need this data sent back to my Android app.

我遇到的问题:我可以看到打印在 Firebase 控制台日志中的数据,但它没有返回到我的 Android 应用程序.

Problem I faced: I could see the data printed in the Firebase console's log but it doesn't return to my Android app.

我的 Firebase 云函数:

const functions = require("firebase-functions");

exports.order = functions.https.onCall((amnt, response) => {
  const Ippopay = require('node-ippopay');

  const ippopay_instance = new Ippopay({
    public_key: 'YOUR_PUBLIC_KEY',
    secret_key: 'YOUR_SECRET_KEY',
  });
    
  ippopay_instance.createOrder({
    amount: amnt, 
    currency: 'DOLLAR',
    payment_modes: "cc,dc,nb,cheque",
    customer: {
      name: "Test",
      email: "test@gmail.com",
      phone: {
        country_code: "42",
        national_number: "4376543210"
      }
    }
  }, function (err, data) {
    return data.order.order_id;
  });
});

我的 Android 客户端代码:

public class Payment extends AppCompatActivity implements IppoPayListener {
    Button pay;
    EditText amount;
    private FirebaseFunctions mFunctions;

    TextView order_data;
    String data;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_payment);
    }
    
    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        pay=findViewById(R.id.pay_button);
        amount=findViewById(R.id.user_amount);
        order_data=findViewById(R.id.data_text);
        pay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("PAY Button clicked", "yes");
                mFunctions = FirebaseFunctions.getInstance("us-central1");
               
                mFunctions.getHttpsCallable("order").call(5).continueWith(new Continuation<HttpsCallableResult, Object>() {
                    @Override
                    public Object then(@NonNull Task<HttpsCallableResult> task) throws Exception {
                        HttpsCallableResult result=task.getResult();
                        if(result !=null)
                        {
                            data=result.getData().toString();
                            return result.getData().toString();

                        }
                        return null;
                    }
                });
                order_data.setText(data);
                onPaymentClick();
            }
        });
    }
    
    /* ... */
}

我是初学者,所以很可能会犯一些愚蠢的错误.:)

I'm a Beginner so there's a high possibility of some dead silly mistakes. :)

推荐答案

根据您的代码目前的样子,您可以混合来自 Callable Cloud Function 和较旧的 HTTP请求云函数.

Based on what your code looks like at the moment, you have a mix of code from a Callable Cloud Function and the older HTTP Request Cloud Function.

要从可调用的云函数返回数据,您应该返回 Promise,一种运行返回值的异步代码的方法.较旧的 JavaScript 和许多其他语言使用回调代替,这就是您在这里所拥有的.

To return data from a callable Cloud Function, you should return a Promise, a method of running asynchronous code that returns a value. Older JavaScript and many other languages use callbacks instead, which is what you have here.

以最简单的形式,这个基于回调的方法:

In it's simplest form, this callback-based method:

someModule.doSomething(input, function (err, result) {
  // check for errors and handle result
});

将转换为使用 Promises 使用:

would be converted to use Promises using:

new Promise((resolve, reject) => {
  someModule.doSomething(
    input,
    (err, result) => err ? reject(err) : resolve(result) // short form of "if error, reject with an error, otherwise resolve (succeed) with result"
  )
});

为了让客户正确处理错误,您需要包装所有错误functions.https.HttpsError 中一个>.

For errors to be handled correctly by clients, you need to wrap any errors in a functions.https.HttpsError.

将这些结合在一起得到:

Combining this together gives:

const functions = require("firebase-functions");

exports.order = functions.https.onCall((amnt, context) => {
  const Ippopay = require('node-ippopay');
  return new Promise((resolve, reject) => {

    const ippopay_instance = new Ippopay({
      public_key: 'YOUR_PUBLIC_KEY',
      secret_key: 'YOUR_SECRET_KEY',
    });
    
    ippopay_instance.createOrder({
      amount: amnt, 
      currency: 'DOLLAR',
      payment_modes: "cc,dc,nb,cheque",
      customer: {
        name: "Test",
        email: "test@gmail.com",
        phone: {
          country_code: "42",
          national_number: "4376543210"
        }
      }
    }, function (err, data) {
      if (err) {
        // something went wrong, send error back to caller
        reject(new functions.https.HttpsError('unknown', 'Ippopay threw an unexpected error', err));
        return;
      }
     
      // successful, send data back to caller
      resolve(data.order.order_id);
    }); 
  });
});

您还应该确保使用 context.auth 来限制对该函数的访问.您不会想向错误的客户收费.

You should also make sure you make use of context.auth to restrict access to this function. You wouldn't want to bill the wrong customer.

这篇关于从 Firebase 函数返回数据到 Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆