Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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]
like image 543
4bottiglie Avatar asked Nov 06 '17 15:11

4bottiglie


People also ask

What are the disadvantages of Firebase?

The cons of Firebase One of the main problems with it, is limited querying capabilities. Realtime database provides no way to filter capabilities, because the whole DB is a huge JSON file, which makes it pretty difficult to make complex queries.

Does Firebase Auth work offline?

By enabling persistence, any data that the Firebase Realtime Database client would sync while online persists to disk and is available offline, even when the user or operating system restarts the app. This means your app works as it would online by using the local data stored in the cache.

What is orderByChild in Firebase?

Inherited from Query.orderByChild. Generates a new Query object ordered by the specified child key. Queries can only order by one key at a time. Calling orderByChild() multiple times on the same query is an error. Firebase queries allow you to order your data by any child key on the fly.27-Jul-2022.

How much traffic can Firebase handle?

The limit on write operations per second on a single database. While not a hard limit, if you sustain more than 1,000 writes per second, your write activity may be rate-limited. 256 MB from the REST API; 16 MB from the SDKs. The total data in each write operation should be less than 256 MB.


1 Answers

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.

like image 135
4bottiglie Avatar answered Oct 05 '22 02:10

4bottiglie