简体   繁体   中英

StackOverflow error with Firebase, while using setValue() method on my Android Project

I store each event that user attends and has created. I suppose, the lists that are stored in User cause StackOverflow error while using .setValue( user).

public class User {

        //Field
        private String name;
        private String email;
        private List<Event> attending_events = new ArrayList<Event>();
        private List<Event> created_events = new ArrayList<Event>();
    }

Without users attending any events, their lists are empty and I can use .setValue(user) without any problem. However, once I add events to users' attending_events, I get StackOverflow error.

    public boolean joinEvent(){

        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference events = database.getReference().child( "events");
        DatabaseReference users = database.getReference().child( "users");

        String type = event.getType();
        DatabaseReference event_type = events.child( type);

     event.setNumberOfCurrentParticipants(event.getNumberOfCurrentParticipants() ++);

        event.setRateOfParticipants();
        event.add( user);

        FirebaseClass.updateEvent( event_type, event);

        user.getAttending_events().add( event);


        users.child(user.getName()).setValue( user); // StackOverflow
}

And the Error message is:

java.lang.StackOverflowError: stack size 8MB
    at java.lang.reflect.Method.invoke(Native Method)
    at com.google.android.gms.internal.firebase_database.zzku.zzm(Unknown Source:58)
    at com.google.android.gms.internal.firebase_database.zzkt.zzi(Unknown Source:237)
    at com.google.android.gms.internal.firebase_database.zzkt.zzi(Unknown Source:191)
    at com.google.android.gms.internal.firebase_database.zzkt.zzl(Unknown Source:0)
    at com.google.android.gms.internal.firebase_database.zzku.zzm(Unknown Source:120)
    at com.google.android.gms.internal.firebase_database.zzkt.zzi(Unknown Source:237)
    at com.google.android.gms.internal.firebase_database.zzkt.zzi(Unknown Source:191)
    at com.google.android.gms.internal.firebase_database.zzkt.zzl(Unknown Source:0)
    at com.google.android.gms.internal.firebase_database.zzku.zzm(Unknown Source:120)
    at com.google.android.gms.internal.firebase_database.zzkt.zzi(Unknown Source:237)
    at com.google.android.gms.internal.firebase_database.zzkt.zzi(Unknown Source:191)
    at com.google.android.gms.internal.firebase_database.zzkt.zzl(Unknown Source:0)
    at com.google.android.gms.internal.firebase_database.zzku.zzm(Unknown Source:120)
    ...

How do I solve this?

My Event class, excluded getters and setters.

public class Event {

//Properties
private String title;
private String place;
private String date;
private String deadline;
private int numberOfCurrentParticipants;
private int numberOfParticipants;
private String description;
private String type;
private String userName;
private double rateOfParticipants;
private ArrayList<User> user_list;
private String key;

/**
 * Empty Constructor
 */
public Event(){
    user_list = new ArrayList<User>();
}

public Event( String title, String place, String date, String deadline, int numberOfParticipants, String description, String userName) {
    this.title = title;
    this.place = place;
    this.date = date;
    this.deadline = deadline;
    this.numberOfParticipants = numberOfParticipants;
    this.description = description;
    this.userName = userName;
    numberOfCurrentParticipants = 1;
    type = null;
    setRateOfParticipants();
    user_list = new ArrayList<User>();
}


public void add( User user)
{
    user_list.add( user);
}
public void remove( User user)
{
    int index = -1;
    for(int i = 0; i < user_list.size(); i ++)
    {
        if( user_list.get( i).equals( user))
            index = i;
    }
    user_list.remove( index);
}

And my FirebaseClass.updateEvent() method. (This also gives stackoverflow error) :

public static void updateEvent( final DatabaseReference ref, final Event event)
{
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Iterable<DataSnapshot> events = dataSnapshot.getChildren();
            for(DataSnapshot snapshot : events){
                Event temp = snapshot.getValue(Event.class);
                if(temp.getTitle().equals(event.getTitle()) && temp.getDescription().equals(event.getDescription())) {
                    snapshot.getRef().setValue(event); // StackOverflow

                }
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

[SOLVED]

I realized that I was trying to store users inside event's user_list and all users have attending_list which also stores events with user_list. Therefore, there are recursive branches of lists. Then, this causes android studio to throw stackoverflow error.

I expect that your the Event class to contains a User property, which then adds not just the user, but also that user's events. Since an event that the user is at, also means that the user is at that event, you have an infinite loop. Because the event adds the user, who in turn adds the event, which in turn adds the user, which adds the event,... until the stack overflows.

To prevent the stack overflow, either remove the nesting of either users in an event, or an event in users, or don't write it to the database by annotating it with @Exclude .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM