How to execute firebase function synchronously inside for loop?

firebase functions async/await
firebase async/await
firebase functions promise
firestore promise all
firestore async/await
wait until firebase retrieve data javascript
wait until firebase retrieve data android
firebase asynchronous android

I am retrieving data from firebase database inside for loop , but problem is that firebase functions are not execute synchronously , i know firebase functions are asynchronous . is there any solution for that ?

Code :-

registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
        {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                peopleModelList.clear();

                for(DataSnapshot snapshot : dataSnapshot.getChildren())
                {
                    peopleModel = new PeopleModel();

                    peopleHashMap =(HashMap)snapshot.getValue();

                    peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
                    peopleModel.setNickname((String)peopleHashMap.get("nickname"));
                    peopleModel.setChatRoom(snapshot.getKey());

                    Log.d("kkkk","1st");

                    if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
                    {
                        registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                peopleModel.setRefresh_token((String)dataSnapshot.child("refresh_token").getValue());
                                peopleModelList.add(peopleModel);
                                Log.d("kkkk","2nd");
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }
                        });
                    }
                    Log.d("kkkk","3rd");

                }
                iCallBackPeople.peopleAct(peopleModelList);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });

Output :-

1st
3rd
2nd

But i want output like this

1st
2nd
3rd

Note :- i searched , but never got any solution !

How to get data from Firebase Database in a loop?

Firebase addListenerForSingleValueEvent excute later in loop

I tried this but not worked for me, it is fill my list with last item !

public void listOfUsers(final ICallBackPeople iCallBackPeople) {
        count=0;
        //peopleModelList = new ArrayList<>();
        sortedMap = new TreeMap<>();
       // peopleModelList = new ArrayList<PeopleModel>(sortedMap.values());
        registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
        {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
             //   peopleModelList.clear();

                for(DataSnapshot snapshot : dataSnapshot.getChildren())
                {
                    peopleModel = new PeopleModel();

                    peopleHashMap =(HashMap)snapshot.getValue();

                    peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
                    peopleModel.setNickname((String)peopleHashMap.get("nickname"));
                    peopleModel.setChatRoom(snapshot.getKey());

                    //Object chatRoom = snapshot.getKey();
                    Log.d("kkkk","1st");

                    if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
                    {

                        addItem(count,iCallBackPeople);
                        count++;
                    }
                    Log.d("kkkk","3rd");

                }
                Log.d("kkkk","end");
                //iCallBackPeople.peopleAct(peopleModelList);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
    }

    private void addItem(final int index, final ICallBackPeople iCallBackPeople) {
        registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                peopleModel.setRefresh_token((String)dataSnapshot.child("refresh_token").getValue());
                Log.d("kkkk","2nd");
                sortedMap.put(index, peopleModel);
                // sortedMap will sort your list by key (in this case, key is integer)


                 if(sortedMap.size()==2)
                 {
                     peopleModelList = new ArrayList<PeopleModel>(sortedMap.values());
                     iCallBackPeople.peopleAct(peopleModelList);
                 }

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

I tried this but not getting all of the item only getting list with last item in snapshot

public void listOfUsers(final ICallBackPeople iCallBackPeople) {

        peopleModelList = new ArrayList<>();

        registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
        {
            PeopleModel peopleModel;
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                peopleModelList.clear();

                for(final DataSnapshot snapshot : dataSnapshot.getChildren())
                {
                    peopleModel = new PeopleModel();

                    peopleHashMap =(HashMap)snapshot.getValue();

                    peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
                    peopleModel.setNickname((String)peopleHashMap.get("nickname"));
                    peopleModel.setChatRoom(snapshot.getKey());


                    if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
                    {
                        getToken(new CallBackGetToken() {
                            @Override
                            public void token(String token) {
                                peopleModel.setRefresh_token(token);
                                Toast.makeText(context, token, Toast.LENGTH_SHORT).show();
                                peopleModelList.add(peopleModel);

                                //here i am checking my peopleModelList size is equal or not to snapshot
                                if(peopleModelList.size()==2)
                                    iCallBackPeople.peopleAct(peopleModelList);
                            }
                        },peopleModel);
                    }
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
    }

    private void getToken(final CallBackGetToken callBackGetToken ,PeopleModel peopleModel) {
        registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                callBackGetToken.token((String)dataSnapshot.child("refresh_token").getValue());
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }
                        });
    }

I think you should pass through an interface(create one and implement at this class). the method inside the interface should have a string as a parameter (it will receive your peopleModel.getChatWith() ) .

Inside your if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))you should request your interface.

I think is a solution for your asynchronously question.

Sync, async, and promises, Also, you can make sure that the Cloud Functions instance running your function does not shut down Terminate a synchronous function with a return; statement. It also lets you propagate errors similar to try/catch in synchronous code. Terminate a synchronous function with a return; statement. Caution: In all cases, be careful to avoid any situation in which the function's result actually retriggers the function — for example, a function triggered by writes to a specific Realtime Database path that concludes by writing to that same path.

Here is my solution:

int count =0;

SortedMap<Integer,PeopleModel> sortedMap;
private void set() {
     count =0;
    registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
    {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            peopleModelList.clear();
            sortedMap = new TreeMap<>();
            for(DataSnapshot snapshot : dataSnapshot.getChildren())
            {
                peopleModel = new PeopleModel();

                peopleHashMap =(HashMap)snapshot.getValue();

                peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
                peopleModel.setNickname((String)peopleHashMap.get("nickname"));
                peopleModel.setChatRoom(snapshot.getKey());

                Log.d("kkkk","1st");

                if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
                {
                    addItem(count);
                    count++;
                }
                Log.d("kkkk","3rd");

            }
            iCallBackPeople.peopleAct(peopleModelList);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

private void addItem(final int index) {
    registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            peopleModel.setRefresh_token((String)dataSnapshot.child("refresh_token").getValue());
            Log.d("kkkk","2nd");
            sortedMap.put(index, peopleModel);
            // sortedMap will sort your list by key (in this case, key is integer)
            // you can get peopleModelList = new ArrayList<>(sortedMap.values);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

Why are the Firebase API asynchronous?, Calling a synchronous function on your app's main thread could freeze So, if one of those bits of work in the event loop takes too long, it'll get  Firebase Cloud Functions is a hosted, private, and scalable Node.js environment where you can run JavaScript code. Firebase SDK for Cloud Functions integrates the Firebase platform by letting you write code that responds to events and invokes functionality exposed by other Firebase features. So, what exactly are Firebase Cloud Functions?

Maybe I'm over simplifying it, but I feel like you should just use simple recursion.

List<People> peopleList;
int currentIndex = 0

private void myFirebaseMethodAction(person){
     registerListener.onCallbacks(new ValueListener(){
             onDataChanged(){
                  person.addStufforDoStuff();
                  if(peopleList.size > currentIndex + 1){
                      myFirebaseMethodAction(peopleList.get(++currentIndex)
                  }
             }
             onFailed(){
                  //handle it
             }
     }
}

Does that make sense? Just saying walk the list with an index, simple. btw above is pseduo code, don't copy verbatim lol.

Serverless Web Applications with React and Firebase: Develop , The advantage of the Cloud Functions is that you don't need to procure any servers on your you terminate your function properly and don't keep your function running in an infinite loop, End a synchronous function with a return; statement  Lifecycle of a background function. The developer writes code for a new function, selecting an event provider (such as Realtime Database), and defining the conditions under which the function should execute. The developer deploys the function, and Firebase connects it to the selected event provider.

How to Interact With a Database Using Async Functions in Node.js , Placing the new async keyword before the function statement or in the async function is paused; the remaining synchronous code in call  The Firebase CLI automatically installs the Firebase and Firebase SDK for Cloud Functions Node modules when you initialize your project. To add 3rd party libraries to your project, you can modify package.json and run npm install. For more information, see Handle Dependencies. Add the addMessage() function

The Top 10 Most Common Mistakes That Node.js Developers Make , If the event loop was being blocked by a loop written to compute the sum of a long history of Mistake #4: Expecting Callbacks to Run Synchronously However, in JavaScript, with callbacks a particular function may not run well until the task  async/await is freaking awesome, but there is one place where it’s tricky: inside a forEach()

Synchronous loop in javascript using async/await and promise , So we will run a loop and be able to wait after each iterations. In this video we will utilize Duration: 3:42 Posted: Jun 19, 2018 That’s it! Now we can deploy our function to our project by opening a terminal in the same location we called “firebase init functions” and running the command: firebase deploy --only functions. If everything went well, you’ll see the function we created under your “Functions” page within the Firebase console.

Comments
  • This doesn't mean that it doesn't work. It works but it only shows the name of the last object. And for that, you should get that statement out of the for loop because for each iteration that statement is called, ending up in having only one item, the last one, right?
  • yea , ex- suppose i having model in which having 3 members , so i am getting 2 data members value before calling callback function and 1 data members value getting after callback function and then put into list!
  • Please resond with @. Also in this case you need to wait for the data.
  • well, i would try to use EventBus, Multithread methods (with RX Android), or even BroadCast Receivers, one of those three certainly should solve your problem.
  • Thank You ! can you provide some link from where i can learn or try something !
  • medium.com/@kevalpatel2106/…
  • where i put peopleModelList = new ArrayList<PeopleModel>(sortedMap.values());?
  • where you want to get peopleModelList
  • in my case sortedMap always filled with last object of peoplemodel only !
  • thanks for your support , actually till now i am not able to solve that problem , by mistakenly i put some wrong code , in my actual code , so result was getting expected but now when i see that wrong code there then i removed wrong code , now i again encounter that problem my list is not getting update .
  • I'm not sure what you are asking now? Your question was how to synchronize your list walk to wait on callbacks. I provided that solution. Are you asking something different now? What list is empty? That wasn't part of your question, so I'm not sure how to respond.