Java – The transaction caused the activity to recall Firebase Android

The transaction caused the activity to recall Firebase Android… here is a solution to the problem.

The transaction caused the activity to recall Firebase Android

When I click on My rate_btn to launch this trading feature.

It works fine, but in the process it reruns my class activity again (my class activity reruns every time a transaction is used), so resets everything like my msg_ID.

For example, my msg_ID changes every time such an activity is called (due to the use of random), so when I run the transaction it works but as a return, it also runs the class activity, thus changing my < strong>msg_ID too.

Here’s a scenario:

so when click this “rate” button it does the rating
on the current msg_ID but when I click on it again, it rates a different
msg_ID because of my get random msg_ID. I think this is caused when
I call the onComplete method.

When I click on rate_btn

vote up the first key

Now that the class starts over, I click rate_btn again.

vote up second key

It votes for the first msg_id and

then when I hit rate_btn again, it votes for the second key (because it recalls the class Activity and msg_id has changed).

Here is the transaction code:

rate_btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
        Firebase upvoteref = new Firebase("https://myapp.firebaseio.com/"+msgID+"/upvotes"); 

upvoteref.runTransaction(new Transaction.Handler() {
            @Override
            public Transaction.Result doTransaction(final MutableData currentData) {
                if (currentData.getValue() == null) {
                    currentData.setValue(1);
                } else {
                    currentData.setValue((Long) currentData.getValue() + 1);
                }

return Transaction.success(currentData);
            }

public void onComplete(FirebaseError firebaseError, boolean committed, DataSnapshot currentData) {
                if (firebaseError != null) {
                    System.out.println("Firebase counter increment failed.");
                } else {
                    System.out.println("Firebase counter increment succeeded.");
                }
            }
        });
    }

Here’s the code to get the random ID:

    String msgID; this variable is declare at the start of the class as a global variable.

Firebase ref = new Firebase("https://myapp.firebaseio.com/"+msgID); 

ref.addValueEventListener(new ValueEventListener() {

public void onDataChange(DataSnapshot snapshot) {
            Iterable<DataSnapshot> ds = snapshot.getChildren();

getting maximum number of children
            long allNum = snapshot.getChildrenCount();
            int maxNum = (int)allNum;

getting the random integer from number of children
            int randomNum = new Random().nextInt(maxNum);

Iterator<DataSnapshot> ids = ds.iterator();

int count = 0;

has next will check if there are values in the next iteration , while count is used as a position substitute.
            while(ids.hasNext() && count < randomNum) {
                ids.next();
                count ++;  used as positioning.
            }           

Map<String, Object> newPost = (Map<String, Object>) ids.next().getValue();  ids will take the value in the iterator (iterate at key) 
            getting the message from the key
            msgID = newPost.get("id").toString();
        }

Any ideas?

Solution

Because the message ID changes each time the transaction is invoked,

this is because addValueEventListener, which accepts the change when the transaction is invoked. So, to solve this problem, I added addListenerForSingleValueEvent instead of addValueEventListener and it worked.

For example:

 ref.addListenerForSingleValueEvent(new ValueEventListener() {

public void onDataChange(DataSnapshot snapshot) {
        Iterable<DataSnapshot> ds = snapshot.getChildren();

getting maximum number of children
        long allNum = snapshot.getChildrenCount();
        int maxNum = (int)allNum;

getting the random integer from number of children
        int randomNum = new Random().nextInt(maxNum);

Iterator<DataSnapshot> ids = ds.iterator();

int count = 0;

has next will check if there are values in the next iteration , while count is used as a position substitute.
        while(ids.hasNext() && count < randomNum) {
            ids.next();
            count ++;  used as positioning.
        }           

Map<String, Object> newPost = (Map<String, Object>) ids.next().getValue();  ids will take the value in the iterator (iterate at key) 
        getting the message from the key
        msgID = newPost.get("id").toString();
    }`

Related Problems and Solutions