Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How deal with Firebase offline mode and data push?

When using Firebase, it is recommanded to use the push() command to manage data list. That's really fine, it provides a unique and ordered id for data pushed on the list.

However, when Firebase goes offline (goOffline or NetworkOffline), if the app try to push a data on a list, the completion listener is not triggered, until the app goes back online : so there is no unique id until the line is on again.

1/ Is that the expected/normal behavior ?

2/ I didn"t see in the document (as far I remember), that the push command is working differently (or only in onlinemode) in offline state. Did I miss a line somewhere ?

3/ My use case deal with data that own relationship. It means I want create an object (kind of master) in a list, and then reuse this master object id (provided by the completion listener) to build the relation between the master object and all other relevants objects. How may I deal with this offline state ?

Code Example :

    findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Firebase(getString(R.string.firebase_url)).child("stack").push().setValue(counter++, new Firebase.CompletionListener() {
                @Override
                public void onComplete(FirebaseError firebaseError, Firebase firebase) {
                    ((TextView) findViewById(R.id.textView3)).setText(String.valueOf(counter) + " - " + firebase.toString());
                }

            });
        }
    });

Edit

Here is 4 ways to add data:

Push with Listener

   findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Firebase(getString(R.string.firebase_url)).child("stack").push().setValue(counter++, new Firebase.CompletionListener() {
                @Override
                public void onComplete(FirebaseError firebaseError, Firebase firebase) {
                    ((TextView) findViewById(R.id.textView3)).setText(String.valueOf(counter) + " - " + firebase.toString());
                }

            });
        }
    });

SetValue with Listener

    findViewById(R.id.button4).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Firebase(getString(R.string.firebase_url)).child("stackManual").child(UUID.randomUUID().toString()).setValue(counter++, new Firebase.CompletionListener() {
                @Override
                public void onComplete(FirebaseError firebaseError, Firebase firebase) {
                    ((TextView) findViewById(R.id.textView4)).setText(String.valueOf(counter) + " - " + firebase.toString());
                }

            });
        }
    });

SetValue without Listener

    findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stackManual").child(UUID.randomUUID().toString());
            temp.setValue(counter++);


            ((TextView) findViewById(R.id.textView5)).setText(String.valueOf(counter) + " - " + temp.getKey().toString());
        }

    });

Push without Listener

    findViewById(R.id.button6).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stack").push();
            temp.setValue(counter++);

            ((TextView) findViewById(R.id.textView6)).setText(String.valueOf(counter) + " - " + temp.getKey().toString());
        }

    });

IT APPEAR THAT THE LISTENERS ARE TRIGGERED ONLY WHEN THE DATA ARE IN THE DATABASE ON THE SERVER, AND NOT ON THE LOCAL DB ! - IS THAT CORRECT ? - IS THAT DOCUMENTED ?

Because knowing that, a straight forward asynchronous application is more difficult to build now : encapsulation of asynchronous job may not be performed if offline, may it ?

like image 582
Anthony Avatar asked Nov 12 '15 22:11

Anthony


People also ask

Is it possible to use Firebase 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.

Does Firebase scale automatically?

Lastly, it'll scale massively and automatically. Firebase Functions will just do it automatically for you based on the traffic you receive and at an incredibly low cost.

How do I manually add data to Firebase?

If you open your app from Firebase dashboard, you can add data manually by clicking on the + sign.


1 Answers

so there is no unique id until the line is on again

This last statement is not true. Firebase push ids are generated client-side and are statistically guaranteed to be unique.

You can easily check this by splitting your operation:

Firebase ref = new Firebase(getString(R.string.firebase_url));
Firebase newStackRef = ref.child("stack").push();
System.out.println("New key/push id: "+newStackRef.key());
newStackRef.setValue(counter++, new Firebase.CompletionListener() {

The logging output will show you the new push id, even when you're not connected to the network.

IT APPEAR THAT THE LISTENERS ARE TRIGGERED ONLY WHEN THE DATA ARE IN THE DATABASE ON THE SERVER, AND NOT ON THE LOCAL DB! IS THAT CORRECT ?

The completion listeners will only trigger once the data has been committed on the server.

From the guide on saving data:

If you'd like to know when your data has been committed, you can add a completion listener. Both setValue() and updateChildren() take an optional completion listener that is called when the write has been committed to the database.

However, regular event listeners (like those created with addValueEventListener()) will be triggered both for local and remote edits. These are the listeners you should use to render your UI, etc.

like image 106
Frank van Puffelen Avatar answered Nov 09 '22 23:11

Frank van Puffelen