Aditya Teja
Aditya Teja

Reputation: 63

Android Firebase Database Exception while runTransaction

I am using TransactionHandler to push a data object as there can be concurrency issues. but while doing that I am getting the below exception:

09-15 19:12:20.193 3196-3196/com.teja.twaters D/com.teja.twaters.utils.FirebaseUtil: isComplete - false
09-15 19:12:20.207 3196-3196/com.teja.twaters D/com.teja.twaters.utils.FirebaseUtil: databaseError - DatabaseError: User code called from the Firebase Database runloop threw an exception:
java.lang.StackOverflowError: stack size 1037KB
at java.lang.reflect.Method.invoke(Native Method)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(Unknown Source)
at com.google.android.gms.internal.zzaln.zzbw(Unknown Source)
at com.google.android.gms.internal.zzaln.zzcd(Unknown Source)
at com.google.android.gms.internal.zzaln$zza.zzce(

I did search for this exception during runTransaction, but couldn't find any. Below is the code snippet where I get this exception:

dataSnapshot.getRef().runTransaction(new Transaction.Handler() {
      
@Override

public Transaction.Result doTransaction(MutableData mutableData) {

    mutableData.child(order.getId() + "").setValue(order);
       
    return Transaction.success(mutableData);
    
}

    
@Override

public void onComplete(DatabaseError databaseError, boolean isComplete,    DataSnapshot dataSnapshot) {

    logger.debug("isComplete - " + isComplete);

    if(isComplete){

        logger.debug("dataSnapshot - " + dataSnapshot);

        callback.onSuccess(IConstants.USER_ORDER_SAVED);
    } else {

        logger.debug("databaseError - " + databaseError);

        callback.onSuccess(IConstants.USER_ORDER_SAVE_FAILED);
        
    }
    
}


});

I get this only with runTransaction. But setValue for a child and updateChildren are working good. Someone else faced with this scenario?

UPDATE:

The root cause i found is that, the Order POJO I was using has a sub-class which was not declared as static. I changed that, and everything is working as expected.

Upvotes: 0

Views: 951

Answers (3)

Shrini Jaiswal
Shrini Jaiswal

Reputation: 1090

This occurs if u call FirebaseDatabase.getInstance() at several place . You should create a singleton instance of it and then use it throught out your project . Example :

public class FirebaseUtils{ private static FirebaseDatabase mDatabase;

public static FirebaseDatabase getDatabase() {
    if (mDatabase == null) {
        mDatabase = FirebaseDatabase.getInstance();

    }
    return mDatabase;
} }

and get the database FirebaseUtils.getDatabase();

Upvotes: 0

JacksOnF1re
JacksOnF1re

Reputation: 3512

For further readers... I had the problem that I had a method inside of my POJO called getDBReference(), which was not static and returned the

DatabaseReference

to this POJO instance. Which, then in a transaction was falsely detected by reflection to "add" to the transaction and caused a StackOverFlow.

tl;dr

I forgot to annotate this method with @Exclude, that was the problem.

Upvotes: 0

Bob Snyder
Bob Snyder

Reputation: 38319

The appearance of dataSnapshot.getRef() in the code you posted is a clue that the code is running inside a listener callback. Let's say the listener is on location X. When you call dataSnapshot.getRef().runTransaction(), you are requesting the transaction on the value at location X. That value is the MutableData you get in the doTransaction() callback. In the doTransaction() callback, you are setting the value of a child of X, which is also a change to X itself. This causes the listener to fire again. I suspect that is the loop that is causing the stack overflow.

Also, this answer provides the details of how transactions are performed. It might be helpful.

Upvotes: 1

Related Questions