I have implemented a payment listener in my mainActivity
. It is working, except that the majority of the time it is firing off multiple times (usually 2 or 3 times) for a single payment receipt.
Below is the method that contains the event listener. It is called from my onCreate
method.
You will see that I tried to get around potnetially creating multiple instances of PaymentsRequestBuilder
by making a global variable PaymentsRequestBuilder paymentsRequest;
and checking that it is null at the start of the method if (paymentsRequest == null)
. This didn't work.
I have also established that this is not being called multiple times from onCreate
, and I also tested saving the PagingToken
locally as well as my database in case that was the issue, but it didn't help.
Every now and then, it will only fire once, which is making debugging more frustrating.
I had previously had it that this method was called from another method that is only called on login. The reason I moved it to onCreate
was because I lost the listener too easily and then had to log out and back in to reestablish it.
I'm also using Firebase, in case that is relevant.
private void StellarExternalTransferListener (String StellarID, final String userID, final String StellarPagingToken, final String secretSeed, final Integer piclCount){
Server server = new Server("https://horizon-testnet.stellar.org");
final KeyPair account = KeyPair.fromAccountId(StellarID);
if (paymentsRequest == null) {
// Create an API call to query payments involving the account.
paymentsRequest = server.payments().forAccount(account);
// If some payments have already been handled, start the results from the
// last seen payment.
if (StellarPagingToken != null) {
paymentsRequest.cursor(StellarPagingToken);
}
// `stream` will send each recorded payment, one by one, then keep the
// connection open and continue to send you new payments as they occur.
paymentsRequest.stream(new EventListener<OperationResponse>() {
@Override
public void onEvent(OperationResponse payment) {
// Record the paging token so we can start from here next time.
userRef.child(userID).child("StellarPagingToken").setValue(payment.getPagingToken());
//Transaction records in the Firebase DB will be handled upon Stellar outgoing transaction success. Hence, incoming Stellar
//transactions will only trigger a balance update, and not be responsible for creating records.
Log.d(TAG, "StellarPagingToken: " + payment.getPagingToken());
// The payments stream includes both sent and received payments. We only
// want to process received payments here.
if (payment instanceof PaymentOperationResponse) {
String receivedStellarID = ((PaymentOperationResponse) payment).getTo().getAccountId();
Log.d(TAG, "Known account check: " + account.getAccountId() + " | " + receivedStellarID);
if (!receivedStellarID.equals(account.getAccountId())) {
Log.d(TAG, "Known account: " + account.getAccountId());
} else {
final String senderStellarID = ((PaymentOperationResponse) payment).getFrom().getAccountId();
final String amount = ((PaymentOperationResponse) payment).getAmount();
final String asset = ((PaymentOperationResponse) payment).getAsset().getType();
Log.d(TAG, "External receipt!: " + senderStellarID + " | " + amount + " | " + asset);
stellarIDs.child(senderStellarID).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "dataSnapshot: " + dataSnapshot);
if (!dataSnapshot.exists() & asset.equals("native")) {
DatabaseReference usersPicls = userRef.child(userID).child("PickleCount");
onInboundTransactionConfirm(userID, usersPicls, senderStellarID, PiclConvertedLumenAmount, secretSeed);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
}
});
}
}