wait until firebase retrieves data

wait until firebase retrieve data javascript
wait until firebase retrieve data swift
firebase get user data
retrieve multiple data from firebase android
retrieving data from firebase
firebase promise
retrieve data from firebase kotlin
how to wait for firebase data

I want to build a method that returns a child value in FireBase. I tried to do something like this:

public String getMessage(){

    root.child("MessagesOnLaunch").child("Message").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            message = (String) dataSnapshot.getValue();
            Log.i("4r398", "work");
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            Log.e("error", firebaseError.getMessage());
        }
    });
    return message;
}

The problem is that the method returns null that is probably because the method doesn't wait until the listener finishes and return null because its the default value of message. How can I make this method wait until the listener occurs and then return the value.

Make an interface

 public interface OnGetDataListener {
    //this is for callbacks
    void onSuccess(DataSnapshot dataSnapshot);
    void onStart();
    void onFailure();
}

Declare the following function readData()

public void readData(Firebase ref, final OnGetDataListener listener) {
    listener.onStart();
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            listener.onSuccess(dataSnapshot);
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            listener.onFailure();
        }
    });

}

Call the readData() function as follows

readData(root.child("MessagesOnLaunch").child("Message"), new OnGetDataListener() {
                @Override
                public void onSuccess(DataSnapshot dataSnapshot) {

               //got data from database....now you can use the retrieved data


                }
                @Override
                public void onStart() {
                    //when starting
                    Log.d("ONSTART", "Started");
                }

                @Override
                public void onFailure() {
                    Log.d("onFailure", "Failed");
                }
            });

readData() can be called inside your getMessage() method or even inside onCreate()

Make Android wait until Firebase Database data is retrieved , Link for the code -- http://locinealy.com/3NP7.Duration: 4:35 Posted: Dec 13, 2019 wait until firebase retrieve data android (3) Don't use Firebase as functions that return values - it goes against it's asynchronous nature. Plan code structure that allows Firebase to perform it's task and then within the closure (block) go to the next step.

You can use CountDownLatch. This is how you can use it.

public String getMessage(){
   CountDownLatch done = new CountDownLatch(1);
   final String message[] = {null}; 
   root.child("MessagesOnLaunch").child("Message").addListenerForSingleValueEvent(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        message[0] = (String) dataSnapshot.getValue();
        System.out.println("worked");
        done.countDown();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {
        System.out.println("failed"+firebaseError.getMessage());
    }
});

try {
    done.await(); //it will wait till the response is received from firebase.
} catch(InterruptedException e) {
    e.printStackTrace();
}
return message[0];
}

Retrieving Data, The event listener is called once for the initial state of the data and again anytime the data changes. Note: By default, read and write access to your database is  The data for this event is null This event will be sent if the Firebase Realtime Database Rules cause a read at the requested location to no longer be allowed: auth_revoked: The data for this event is a string indicating that a the credential has expired This event will be sent when the supplied auth parameter is no longer valid

Don't use Firebase as functions that return values - it goes against it's asynchronous nature.

Plan code structure that allows Firebase to perform it's task and then within the closure (block) go to the next step.

In your code, for example, change the function to not return anything and within the onDataChange, as the last line call the next function to update your UI.

and addListenerForSingleValueEvent() of firebase, () executes onDataChange method immediately and after executing that method once, it stops listening to the reference location it is attached to. What I understood is you are trying to save the snapshot data into a variable but due to async task the variable turns out to be null, this is because of the nature of async task, what you could do is pass the snapshot data from firebase listener function to your custom function outside and store the snapshot data into a global variable.Then you can use the variable as like you want to.

As @CMikeB1 commented on another response in the java world when we are dealing with servlets and services rest we use sync calls to perform operations, it would be useful to have both options in sdk firebase admin so that the developer could choose which one to use depending on his case use.

I made my implementation from waiting to read the sync data using ApiFuture which is the current interface adopted by the sdk of the firebase admin. here's a link!

public DataSnapshot getMessage() {
    final SettableApiFuture<DataSnapshot> future = SettableApiFuture.create();
    databaseReference.child("MessagesOnLaunch").child("Message").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            future.set(dataSnapshot);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            future.setException(databaseError.toException());
        }
    });
    try {
        return future.get();
    } catch(InterruptedException | ExecutionException e) {
        e.printStackTrace();
        return null;
    }
}

Wait until a method finish, Preventing that method from continuing until the Firebase database has returned a value would be a bad idea, because it would freeze the  Firebase data is retrieved by either a one time call to GetValueAsync () or attaching to an event on a FirebaseDatabase reference. The event listener is called once for the initial state of the data and again anytime the data changes. Note: By default, read and write access to your database is restricted so only authenticated users can read or

I'll leave this here to help anyone who faces the same problem as me. @Tirupati Singh code looks nice but I wrote my answer below his why it didn't work for me. Using Atomic type worked -

public AtomicInteger getMessage(){
        final AtomicBoolean done = new AtomicBoolean(false);
        final AtomicInteger message1 = new AtomicInteger(0);

        //assuming you have already called firebase initialization code for admin sdk, android etc
       DatabaseReference root = FirebaseDatabase.getInstance().getReference("server");
       root.child("MessagesOnLaunch").child("Message").addListenerForSingleValueEvent(new ValueEventListener() {

        public void onDataChange(DataSnapshot dataSnapshot) {
            message1.set((Integer) dataSnapshot.getValue()); 
            done.set(true);
        }

        public void onCancelled(DatabaseError error) {
            // TODO Auto-generated method stub

        }
    });
    while (!done.get());

    return message1;
}

Note the function can only return message type Integer. I couldn't get it to work for String as no Atomic type for String. Hope this helps!

Why are the Firebase API asynchronous?, Firebase APIs for mobile clients are all asynchronous when reading writing data. returns immediately, without blocking the code to wait for a result. If you want to fetch some data, it's natural to want to write code that's  Wait until complete onChildAdded in firebase querys, Android Is there any way to wait until complete thatonChildAdded method wait until firebase retrieves

Wait Firebase async retrieve data in Android, I need to store the result of FireBase getValue method that is async by his own. I can't use something like "onPostExecute()" and, for my purpose, i can't execute  Make Android wait until Firebase Database data is retrieved Gnana Sreekar. Loading Unsubscribe from Gnana Sreekar? Cancel Unsubscribe. Working Subscribe Subscribed Unsubscribe 1.98K. Loading

How to wait for a change in Firebase value, In Android, if you choose the Realtime Database, listening for changes is as easy as: Retrieving Data | Firebase Realtime Database We are building an Android app, and our database is on Firebase. I want to read a data from the database (let's say store it in a global String variable sampleString) and use it throughout the code. However, when I use a listener, I can only use sampleString inside the listener.

Your Program Isn't Waiting For Firebase-Function To Complete , This blog is about firebase functions that we use for retrieving or writing data into the Firebase realtime-databse. This article is about firebase functions that we use for retrieving or writing data into the Firebase realtime-databse. In some situations, our program is completed before the firebase function could do its work! It is a common problem for people using the firebase technology.

Comments
  • assume root is stored on the class (and the class isn't gc'ed) it shouldn't matter that the function completes
  • You cannot synchronously return an asynchronous value. The message variable here is completely pointless as it's not going to be set at the time it returns--the data has to be fetched from the server first. Instead, getMessage() should either accept a callback of some sort or trigger an event. There is a guide dedicated to these concepts, chocked full of examples and advice.
  • Use this Answer. I have faced the same issue and solved using EventBus.
  • I followed these instructions to the dot, and I'm still experiencing the same exact issue as OP. I don't understand how I'm supposed to structure my code such that I'm able to use the data inside of the Firebase database
  • message is not declared. If you declare message at start of function as String message = null, it has to be declared final too or it won't compile. And then since its final you can't update message anymore within onDataChange. This is so frustrating. Almost no way to get data out of onDataChange to the outside world in a clean piece of code.
  • Awesome way to do this! @Zod Use a final AtomicReference or array wrapper to g/set the message
  • You might also add public synchronized String getMessage() to the method signature to ensure only one thread is calling this method at a time. Without it, empirical testing proved I was getting the wrong message returned about 10% of the time when running this method in parallel (e.g. two or more requests coming into your servlet at the same time, so two threads calling this method at the same time).
  • here I have missed declaring "message" variable which is confusing to the users looking for answers. @NathanAdams is correct. I will edit the answer. Thanks Nathan for clarifying.
  • Damn @TirupatiSingh ! You the real MVP !
  • That's all well and good, but in the rest of the Java world we use servlets and RestTemplates that are synchronous. Google throwing in an asynchronous library really complicates things.
  • yes, possible it is useful just for android use only
  • this is the standard approach but there are scenarios where this just leads to spaghetti code