0

I am developing an Android app in which i need to retrieve data from Firestore during app's splash screen and use a particular value from that document snapshot to retrieve another document. For this I need to get the string value out of Firebase's get() function. But when i try this, I am not getting the value of the variable out of the function:

String userCityL;
    DocumentReference docRef = firestoreDB.collection("users").document(mail);
    docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {
                DocumentSnapshot document = task.getResult();
                String userCityL;
                if (document.exists()) {
                    Log.d(TAG, "DocumentSnapshot data: " + document.getData());

                    userNameL = document.getString("UserName");
                    userPhoneL = document.getString("UserPhoneNo");
                    userDegreeL = document.getString("UserDegree");
                    userSpecialL = document.getString("UserSpecial");
                    userCityL = document.getString("UserCity");
                    userProfilePicL = document.getString("downloadUri");

                    TextView userCity = findViewById(R.id.tvCity);
                    userCity.setText(userCityL);

                    //loadNotesList();

                    //dummy(userCityL);

                    //loadNotesList(userCityL);

                } else {
                    Log.d(TAG, "No such document");
                }
            } else {
                Log.d(TAG, "get failed with ", task.getException());
            }
        }
    });

Here, nothing is being stored in userCityL variable.

3 Answers3

0

You are not getting the value of that String outside the onComplete() function not outside the get() function. This is happening because the onComplete() function has an asynchronous behavior. You also cannot simply create a global variable and use it's value outside the function because it will always be null. If you want to use a value that is coming from the database outside the onDataChange() method, you have two choices. The first one would be to pass the desired object as argument to a method that is defined in your class like this:

docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            if (document.exists()) {
                String userCityL = document.getString("UserCity");
                methodThatDoesSomething(userCityL); //Method call

            } else {
                Log.d(TAG, "No such document");
            }
        } else {
            Log.d(TAG, "get failed with ", task.getException());
        }
    }
});

private void methodThatDoesSomething(String userCityL) {
    //Do what you need to do with your userCityL object
}

Or, if you want it in a more complex way, then dive into the asynchronous world of modern API's and see the last part of my answer in this post, in which I have explained step by step how you can achieve this using a custom callback. For more informations, you can take also a look at this video.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • calling the function from within the if condition passes the value to the function successfully. Thanks for that :) can u pls let me know how to assign that value to a variable that i declared in main class ? I tried all the ways but cannot get this done. – Karthic Srinivasan Jun 19 '18 at 12:21
  • You cannot simply declare a variable as global but you can solve this using the last part of my answer from this **[post](https://stackoverflow.com/questions/48499310/firestore-object-with-inner-object/48500679)**. – Alex Mamo Jun 19 '18 at 12:26
0

It is, but the you are problably calling the string before getting the result from the fucntion.

Try and put the function where you call the string inside that function.

check Alex Mamo video where you have the explanation.

-1

I solved this problem using "shared preferences". My problem is to fetch user data of the user who is currently logging in and use this data across my entire app in all the activities. Here i fetch the data from firebase during the splash screen and store it in shared preference file and use those data in other activities. Thanks :)

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • This is not even a partial solution because `SharedPreferences` does not persist across applications uninstall. If you reinstall the app, your `SharedPreferences` will be empty, you will not be able to use user details at all. Beside that, you can store only small amount of data. It is very difficult to store and read large structured data. Furthermore you cannot really search within the data except you have a certain concept for naming the keys. And finally, because you have used `google-cloud-firestore` as a tag, you need to know that in `SharedPreferences` doesn't have a real-time feature. – Alex Mamo Jul 12 '18 at 15:59
  • And your solution also doesn't answer your `use firestore document data outside get function in android` question at all. I don't recommend this solution for future visitors. – Alex Mamo Jul 12 '18 at 16:02
  • If an user is already logged into the app, the above code will read his data from cloudfirestore and store in sharedpreference. If the user is not signedin, it will redirected to registration activity or signin activity. Once the user login or register, again it will get the data from firestore and populate sharedpreference file. It perfectly answers my question. Your answer didn't worked for me. This solution was perfect for my scenario. Yours was just half of the solution. – Karthic Srinivasan Jul 20 '18 at 08:32
  • If you reinstall the app, your SharedPreferences will be empty --> Yes SharedPreferences will be emptied when we reinstall the app. But I clearly mentioned that data will be retrieved from firestore during splashscreen next time you launch the app. It is very difficult to store and read large structured data --> In this scenario, i have only 6 variables to be retrieved from firestore. So SharedPreferences is the best solution for me. I hope stackoverflow is to get solution for a particular problem and not to get generic answer for all problems :) – Karthic Srinivasan Jul 20 '18 at 08:42
  • You should edit your post and put into it how you solve your problem for future references. – Genaro Alberto Cancino Herrera Jul 20 '18 at 13:31