我正在使用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);
}
});
}
答案 0 :(得分:1)
您无法将rideAmt
创建为全局变量,而只能在payPalPayment()
方法内使用它,因为Firebase API是异步的,这意味着onDataChange()
方法在调用后立即返回,并且它返回的Task的回调将在一段时间后调用。无法保证需要多长时间。因此,可能需要几百毫秒到几秒钟的时间才能获得该数据。由于该方法会立即返回,因此您尚未尝试从rideAmt
方法之外使用它的onDataChange()
变量的值。
基本上,您正在尝试从异步API同步使用rideAmt
的值。那不是一个好主意。您应该按预期异步处理API。
对此问题的快速解决方案是将payPalPayment()
方法中存在的所有逻辑移到onDataChange()
方法内部。这样,您尝试获取的数据将在那时可用。
如果需要在回调之外使用它,我建议您从此 post 中查看anwser的最后一部分,其中我已经解释了如何使用自定义功能打回来。您也可以查看此 video 以获得更好的理解。