firebase / FirebaseUI-Android

Optimized UI components for Firebase
https://firebaseopensource.com/projects/firebase/firebaseui-android/
Apache License 2.0
4.63k stars 1.84k forks source link

Weird crash on FirebaseArray.onChildAdded #1291

Open matteobucci opened 6 years ago

matteobucci commented 6 years ago

I've just received on Crashlytics a crash that doens't seem to be my code fault but I don't understand what could be the reason of it.

This is the exception: Fatal Exception: java.lang.IllegalArgumentException Key not found

This the stack: com.firebase.ui.database.FirebaseArray.onChildAdded (Unknown Source) com.firebase.ui.database.FirebaseArray.onCreate (Unknown Source) com.google.android.gms.internal.firebase_database.zzbt.zza (Unknown Source) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:762)

These the details about the device and the version of the libraries I use

What could it be? Is there any reason why this error should show up?

samtstern commented 6 years ago

Here are the relevant bits of code from FirebaseArray:

    @Override
    public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
        int index = 0;
        if (previousChildKey != null) {
            index = getIndexForKey(previousChildKey) + 1;
        }

        mSnapshots.add(index, snapshot);
        notifyOnChildChanged(ChangeEventType.ADDED, snapshot, index, -1);
    }

// ...

    private int getIndexForKey(String key) {
        int index = 0;
        for (DataSnapshot snapshot : mSnapshots) {
            if (snapshot.getKey().equals(key)) {
                return index;
            } else {
                index++;
            }
        }
        throw new IllegalArgumentException("Key not found");
    }

So somehow we're getting an onChildAdded event where the previousChildKey is not something we have seen before.

@matteobucci how often do you see this crash?

puf commented 6 years ago

The only thing I can think of here is a race condition between the optimistic client-side events and the server-triggered reconciliation events. But I've never seen anything like that before.

@matteobucci Can you indeed share a bit more on the frequency and context of this error?

diousk commented 6 years ago

Hi @puf , I have a similar issue on"onChildRemoved" (and also on"onChildAdded")

Fatal Exception: java.lang.IllegalArgumentException
Key not found
com.firebase.ui.database.FirebaseArray.getIndexForKey (FirebaseArray.java:121)
com.firebase.ui.database.FirebaseArray.onChildRemoved (FirebaseArray.java:85)
Fatal Exception: java.lang.IllegalArgumentException
Key not found
com.firebase.ui.database.FirebaseArray.getIndexForKey (FirebaseArray.java:121)
com.firebase.ui.database.FirebaseArray.onChildAdded (FirebaseArray.java:68)

I have two chat rooms and both of the data references to the same database reference. And both of the database references are set to ref.limitToLast(100) and pass to FirebaseRecyclerOptions.

On the UI, user can switch between them.

From our fabric crashlytics log, the issue happens just when user switch the chat room from one to another (not every time).

the code snapshot to switch: (first we detach current adapter from current RecyclerView and create a new adapter to attach to another RecyclerView)

private void detachRecyclerViewAdapter() {
        RecyclerView.Adapter adapter = mMessagesRecyclerView1.getAdapter();

        ((FirebaseRecyclerAdapter) adapter).stopListening();
        if (adapter.hasObservers()) {
            adapter.unregisterAdapterDataObserver(dataObserver);
        }

        mMessagesRecyclerView1.setAdapter(null);
    }
private void attachRecyclerViewAdapter() {
        FirebaseRecyclerAdapter adapter = newAdapter();
        adapter.registerAdapterDataObserver(dataObserver);
        mMessagesRecyclerView2.setAdapter(adapter);
        adapter.startListening();
    }
private FirebaseRecyclerAdapter newAdapter() {
        Query messageQuery = ref.limitToLast(100);
        messageQuery.keepSynced(true);
        FirebaseRecyclerOptions<ChatMessage> options =
                new FirebaseRecyclerOptions.Builder<ChatMessage>()
                        .setQuery(messageQuery, ChatMessage.class)
                        .build();

        return new FirebaseRecyclerAdapter<...>(options) {...}

Hope this information helps.

abhishek-bharadwaj commented 6 years ago

@puf even we are the same issue and in last 30 days, it crashed for 30+ users more than 50 times. We are getting the issue in onChildAdded. I am attaching full stacktrace.

Fatal Exception: java.lang.IllegalArgumentException: Key not found at com.firebase.ui.database.FirebaseArray.getIndexForKey(FirebaseArray.java:121) at com.firebase.ui.database.FirebaseArray.onChildAdded(FirebaseArray.java:68) at com.google.android.gms.internal.zzegg.zza(Unknown Source) at com.google.android.gms.internal.zzelk.zzcal(Unknown Source) at com.google.android.gms.internal.zzelq.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:754) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:163) at android.app.ActivityThread.main(ActivityThread.java:6379) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

matteobucci commented 6 years ago

@puf sorry for the delay, but I don't think I can provide more information about this error than the ones I provided. The error occured once again in another device, during the opening of a screen where I just read some read-only data and start listening to child removed.

oscardelgado commented 4 years ago

Anyone had any luck with this?