如何从侦听器获取数据?

时间:2019-03-18 01:21:43

标签: java android firebase firebase-realtime-database

我正在使用Android和iOS和Firebase跨平台开发我的应用程序。在iOS应用中,驾驶员可以选择使用出价来请求所请求的旅程,而在Android应用中,这只是计算得出的价格。

如果Android驾驶员请求使用iOS驱动程序,则iOS驱动程序可以提供折扣出价,而不是计算出的ridePrice。

在Firebase中,在RideRequests节点中,它添加ridePrice作为要支付的价格,但是,如果它是一个出价,它也会添加一个bidPrice。我试图将其设置为:如果存在'rideBidPrice',则为rideAmt = rideBidPrice,否则为rideAmt = ridePrice

不幸的是,我正在做的并不是去使用PayPalPayment方法。

我该怎么做?

firebase数据库:

"RideRequests" : {
    "buIpWNEFgmZJWN3jIB9IwS8r74d2" : { // rider Id
      "archiveTimestamp" : "2019-03-17 22:00",
      "currentAddress" : "2 Peel Plaza",
      "destAddress" : "Courtenay Bay Causeway",
      "destLat" : 47.277879500000004,
      "destLong" : -63.04432369999999,
      "driver" : "Dean Winchester",
      "driverID" : "nD1v8oxHv3ObdQAKeKjuTt6f5TL2",
      "rideBidPrice" : 5.74,
      "ridePrice" : 8.38,
      "riderPaid" : "false",
      "status" : "driverBid",
      "userId" : "buIpWNEFgmZJWN3jIB9IwS8r74d2",
      "username" : "riderANDROID"
    }

代码:

private void checkForBids() {

    Log.e(TAG, "checkForBids");

    DatabaseReference bids = FirebaseDatabase.getInstance().getReference(Common.request_tbl)
            .child(riderId).child("rideBidPrice");
    bids.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            bidPrice = dataSnapshot.getValue(Double.class);
            if (bidPrice != null) {
                rideAmt = bidPrice;
            } else {
                rideAmt = ridePrice;
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}


private void payPalPayment() {

    Log.e(TAG, "payPalPayment");

    PayPalPayment payment = new PayPalPayment(new BigDecimal(rideAmt),
                "CAD", "Ryyde Payment ", PayPalPayment.PAYMENT_INTENT_SALE);

    // PaymentActivity is created by PayPal API
    Intent intent = new Intent(this, PaymentActivity.class);

    intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
    intent.putExtra(PaymentActivity.EXTRA_PAYMENT, payment);

    startActivityForResult(intent, PAYPAL_REQUEST_CODE);
}

我还尝试将payPalPayment方法放入块中,但由于意图而无法正常工作。

编辑#1

这有效:

根据@AlexMamo到以下帖子的内容:

How to return DataSnapshot value as a result of a method?

我添加了一个界面:

 public interface MyCallback {
    void onCallback(Double value); 
}

实际上是从数据库中获取数据的方法:

public void readData(final MyCallback myCallback) {

    Log.e(TAG, "readData");

    DatabaseReference bids = FirebaseDatabase.getInstance().getReference(Common.request_tbl)
            .child(riderId).child("rideBidPrice");
    bids.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Double value = dataSnapshot.getValue(Double.class);
            myCallback.onCallback(value);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

然后我像这样在PayPalPayment方法中调用该方法:

 private void payPalPayment() {

    readData(new MyCallback() {
        @Override
        public void onCallback(Double value) {
            PayPalPayment payment = new PayPalPayment(new BigDecimal(value),
                    "CAD", "Ryyde Payment ", PayPalPayment.PAYMENT_INTENT_SALE);

            // PaymentActivity is created by PayPal API
            Intent intent = new Intent(RiderHome.this, PaymentActivity.class);

            intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, config);
            intent.putExtra(PaymentActivity.EXTRA_PAYMENT, payment);

            startActivityForResult(intent, PAYPAL_REQUEST_CODE);
        }
    });
}

1 个答案:

答案 0 :(得分:1)

您无法将rideAmt创建为全局变量,而只能在payPalPayment()方法内使用它,因为Firebase API是异步的,这意味着onDataChange()方法在调用后立即返回,并且它返回的Task的回调将在一段时间后调用。无法保证需要多长时间。因此,可能需要几百毫秒到几秒钟的时间才能获得该数据。由于该方法会立即返回,因此您尚未尝试从rideAmt方法之外使用它的onDataChange()变量的值。

基本上,您正在尝试从异步API同步使用rideAmt的值。那不是一个好主意。您应该按预期异步处理API。

对此问题的快速解决方案是将payPalPayment()方法中存在的所有逻辑移到onDataChange()方法内部。这样,您尝试获取的数据将在那时可用。

如果需要在回调之外使用它,我建议您从此 post 中查看anwser的最后一部分,其中我已经解释了如何使用自定义功能打回来。您也可以查看此 video 以获得更好的理解。