2

I am trying to get and display my user's information when they are logged in. (i.e: name, email, phone)

I have tried multiple snippets i have found on youtube and on stack overflow but they have failed. Most tutorials use realtime Database, which is not what i am looking for.

I have also tried making a "users" object.

private void getData(){
        FirebaseFirestore db = FirebaseFirestore.getInstance();

        db.collection("users")
                //.document(FirebaseAuth.getInstance().getCurrentUser().getUid())
                .whereEqualTo("email:", FirebaseAuth.getInstance().getCurrentUser().getUid())
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            for (DocumentSnapshot document : task.getResult()) {
                                //Toast.makeText(getApplicationContext(),document.getId() +"==>" + document.getData(),Toast.LENGTH_LONG).show();
                                //Toast.makeText(getApplicationContext(),""+ document.get("Email") ,Toast.LENGTH_LONG).show();

                                nameEdt.setText((CharSequence) document.get("First Name"));
                                emailEdt.setText((CharSequence) document.get("Email"));
                                phoneEdt.setText((CharSequence) document.get("Phone"));


                            }
                        } else {
                            Toast.makeText(getApplicationContext(),"No such document",Toast.LENGTH_LONG).show();
                        }
                    }
                });
    }

Database Structure: db structure

I understand that documents in firestore are not associated with users, but i dont know how to set my code up so that it only retrieves data from the user that is signed in* It works fine for newly created accounts, but if i were to log out and sign in with a different user it will not update the "account/user information".

In short, how would I access and display my database information from signed in users?

Additional Notes: I am using Email and Password for authentication

solid_soap
  • 55
  • 1
  • 10
  • 1
    What is happening when you are using this code? Please also add your database structure. – Alex Mamo May 22 '19 at 07:10
  • @AlexMamo Hi Alex, I have updated my questions with database structure and additional information. It doesnt do anything, doesnt retrieve any data. If i remove "whereEqualTo" it will only retrieve information from an account that was newly created, so if i log out, and sign in with a different user it will only show the previous users information. I believe my issue is that it doesn't know which user is associated with which document but, i am un sure on how to create a link for that – solid_soap May 22 '19 at 19:06
  • Firestore will never have knowledge of it's own data as there are no relationships or other logic. You and your app need to establish how Firestore objects are related. Your structure appears sound - as long as you are using the users uid to create the top level documents with the /users collection. So the concept is when the the user authenticates, you will be able to access their uid, Then you can load their 'other information' from the users node via that uid. – Jay May 22 '19 at 19:06
  • Also, take a look at [Adding new user data](https://stackoverflow.com/questions/46657445/adding-new-data-to-firebase-users/46657503#46657503) as the question is similar and @frankvanpuffelen answer has a number of links for further reading. – Jay May 22 '19 at 19:09

2 Answers2

5

To access your user data stored in Firestore, it shouldn't be as complicated as you thought, there's no queries needed, you just need to fetch the documents corresponding to the user's uid, and fetch the specific fields or do whatever you need with them, like this:

db.collection("users").document(FirebaseAuth.getInstance().getCurrentUser().getUid())
        .get().addOnCompleteListener(task -> {
    if(task.isSuccessful() && task.getResult() != null){
        String firstName = task.getResult().getString("First Name");
        String email = task.getResult().getString("Email");
        String phone = task.getResult().getString("Phone");
        //other stuff
    }else{
        //deal with error
    }
});

Original Answer:

User information is not stored in the Firestore database, they are associated with the Firebase Authentication which you set up for the log in. To retrieve the related user information, you need to use the related FirebaseAuth APIs. Use this to retrieve the current log in user:

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

Then you can get the name and email with something like this:

String name = user.getDisplayName();
String email = user.getEmail();

For more information, refer to the documentation.


If FirebaseAuth doesn't resolve, that probably means you didn't follow the set up guides correctly and forgot to include the dependency in your gradle file:

implementation 'com.google.firebase:firebase-auth:17.0.0'
Jack
  • 5,354
  • 2
  • 29
  • 54
  • With that method i could only access, display name and email and other set functions with firebase. i would need to access my database to be able to retrieve other information a user may input such as: phone number, appointment dates etc – solid_soap May 22 '19 at 04:41
  • well for the other information it's entirely up to how you set up your firestore to work and then you can retrieve them, there's no native way to store extra info on a user AFAIK. – Jack May 22 '19 at 04:44
  • If you are wondering on how to set up your database to store extra info for your users, you should edit your question so that your intention is clearer. But even then there are countless ways you can do that, you should look into it more and see what kind of structure do you want, and then start from there. – Jack May 22 '19 at 05:00
  • @solid_soap Looking at the original question, the OP clearly has a */users* node in their database which stores additional information such as First Name so I believe that's what they want to load and what they are asking about. They also state *I understand that documents in firestore are not associated with users*. While this answer has really good information about getting predefined fields from Authentication, it doesn't address the original question. Can you update to also answer that? – Jay May 22 '19 at 16:08
  • @Jay i think you meant to reply to jackz314, if i am not mistaken – solid_soap May 22 '19 at 18:58
  • @solid_soap Nope. That was meant for you. I wanted to bring your attention to it quickly so you didn't spend time going down the wrong path. It's good information but doesn't address your question directly. – Jay May 22 '19 at 19:04
  • @Jay Like I said in the first comment, there's countless ways you can store extra user information in firestore and it's entirely up to how you want it to be. Since OP didn't post any existing data structures in firestore, I'm assuming he didn't set the storing mechanism up yet, therefore there's no way I can answer on how to get these extra info without having a clear data structure defined. – Jack May 22 '19 at 21:52
  • @jackz314 Understood and agreed. The structure can be seen in the included screen shot or derived from his code. I feel an answer should attempt to address the actual question which ultimately is *how do I retrieve data from a node in Firestore with a known key* – Jay May 23 '19 at 12:22
  • To be fair, the original question was not clear on that, but anyways, I just saw the updated database structure and updated my answer. – Jack May 24 '19 at 00:34
  • And that sir, is an excellent answer which directly addresses the question! An up arrow for you. @solid_soap This is really on point - be sure to accept it if it helps. – Jay May 24 '19 at 15:17
  • @jackz314 ill be sure to do my best to improve the quality of my questions in the future, my apologies. However, if you actually look at my post you will see that i have already attempted that method you posted above and it didnt work me. But i did figure it out-- and havent had the time to post the answer – solid_soap May 25 '19 at 18:35
1

After a couple days head butting at trying to find a solution, i have found one that is able to retrieve user information from the database. However it is important to note that because my application is not holding a lot of data so this structure works for me.

So i was essentially on the right track, but with some lack of understanding of firebase i missed a few concepts.

    private void getData(){
        FirebaseFirestore db = FirebaseFirestore.getInstance();
        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        final String current = user.getUid();//getting unique user id

        db.collection("users")
                .whereEqualTo("uId",current)//looks for the corresponding value with the field
                // in the database
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            for (DocumentSnapshot document : task.getResult()) {

                                nameEdt.setText((CharSequence) document.get("firstName"));
                                emailEdt.setText((CharSequence) document.get("email"));
                                phoneEdt.setText((CharSequence) document.get("phone"));
                                // These values must exactly match the fields you have in your db

                            }
                        } 

As mentioned before, documents do not associate with users, but you CAN link them together by creating a field in your db called "whatever your want" (i made mine uId). This is because firebase generates a unique id for each user when authenticated. By creating a field that holds that unique id you are able to retrieve the associated information in that collection.

bd struc

How to create the field: I created a "user" object that would grab the uid from my edit text. In my code, i passed the uid wherever i was creating/authenticating a new user/account.

FirebaseUser testUser = FirebaseAuth.getInstance().getCurrentUser(); //getting the current logged in users id
                            String userUid = testUser.getUid();                       
                            String uidInput = userUid;

User user = new User(firstNameInput,lastNameInput,uidInput);

 db.collection("users").document(userUid)
                                    .set(user)
                                    .addOnSuccessListener(new OnSuccessListener<Void>() {

note: I believe you can also add it to your hash map if you have it done that way.

solid_soap
  • 55
  • 1
  • 10