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
Now that the class starts over, I click rate_btn again.
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();
}`