4bottiglie
4bottiglie

Reputation: 540

Firebase Database not committing online data blocking Listeners

I am using the Firebase Database service to synchronize users data. I enabled the offline compatibilities and the problem is that after some months the of usage, the users data is not committed into the online database apparently because the users phone systems are blocking the application internet connection.

In some cases, i managed to guide the users enable the "unlimited data usage" option, but isn't working for everyone.

In my case, the problem is that the listener:

void onDataChange(DataSnapshot var1);

from ValueEventListener, is not fired when a huge amount of data is stored offline and not committed, and is blocking all the behaviors.

I don't have online storage limitation because I have the Blaze plan ( pay for consuming ).

The transactions are not committed too, and fires "The transaction was overridden by a subsequent set" with the error code -9.

The Connection detector provided by Firebase is always printing "not connected "

I also tried to alternate goOffline() with goOnline() but nothing happens.

I don't understand why the phone could block my app from synchronizing and let apps like Facebook and Youtube to consume a large amount of internet data.

This behavior is only happening on the Android devices, there is no problem on iOS phones that are using the same Firebase Database.

Doesn't work either with 4g, WI-FI nor with VPN ( used Opera VPN ).

Update 1:

The logs contains at launch for ~10 times:

11-13 21:12:28.477 15765 15856 D PersistentConnection: pc_0 - Scheduling connection attempt
11-13 21:12:28.477 15765 15856 D ConnectionRetryHelper: Scheduling retry in 26091ms
11-13 21:12:54.597 15765 15856 D PersistentConnection: pc_0 - Trying to fetch auth token
11-13 21:12:55.747 15765 15856 D PersistentConnection: pc_0 - Error fetching token: An internal error has occurred. [ 
TOKEN_EXPIRED ]

When I'm trying to insert new data:

RepoOperation: Aborting transactions for path: [the path]

Upvotes: 6

Views: 922

Answers (1)

4bottiglie
4bottiglie

Reputation: 540

After a long investigation, I found out that the token was not refreshing automatically.

First of all, check if the current user is logged in with FirebaseAuth.AuthStateListener

To check if I need to refresh the token

1) Check if the application has internet connection:

    public static boolean isOnline(Context context)
    {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        return networkInfo != null && networkInfo.isConnectedOrConnecting();
    }

2) Then I check if the database is connected to: Detecting Connection State

If the app has an internet connection and the database is not connected then I try to refresh the token:

try
{
    user.getIdToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>()
    {
        @Override
        public void onComplete(@NonNull Task<GetTokenResult> task)
        {
            if (task.isSuccessful())
            {
                //succcess
            } else
            {
                //need login again
            }
        }
    });
}catch(Exception e)
{
    //need login again
}

If there is an exception or the completion task fails then I try to login again the user. In most of the cases will be a transparent login, so will not be displayed to the user, because will use the credentials already stored by the sdk itself.

I think this is a hack because affects only a few users so it's an sdk bug.

Upvotes: 4

Related Questions