0
votes

I have a Firebase database of the following:

  • Root Node
  • User node
  • an automatically generated key generated by ref.push()
  • attributes

I am trying to retrieve only one of the attributes of a single child under the user. Here is a screenshot of my database:

Screenshot of my database

If you check the screenshot, i only want to retrieve email (assume i have no other way of getting it). However, in the code, I wouldn't know the child of User that contains the email I want. This is what i am currently doing but it is very inefficient (this code checks if my current user exists, if not, it adds his/her data to the database):

FirebaseDatabase database = FirebaseDatabase.getInstance();
                    DatabaseReference ref = database.getReference("User");

                    ref.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            Iterable<DataSnapshot> children = dataSnapshot.getChildren();
                            for (DataSnapshot child:children) {
                                User user1 = child.getValue(User.class);
                                Log.d("kharas email",user1.getEmail()+"");
                                if(!user1.getEmail().equals(firebaseAuth.getCurrentUser().getEmail())){

                                    GraphRequest.newMeRequest(token, new GraphRequest.GraphJSONObjectCallback() {
                                        String birthday = "Not Available";
                                        @Override
                                        public void onCompleted(JSONObject object, GraphResponse response) {
                                            User userInfo = new User();
                                            FirebaseDatabase database = FirebaseDatabase.getInstance();
                                            DatabaseReference ref = database.getReference("User");
                                            birthday = object.has("email")+"";
                                            userInfo.setBirthday(birthday);
                                            userInfo.setEmail(firebaseAuth.getCurrentUser().getEmail());

                                            ref.push().setValue(userInfo);
                                        }
                                    }).executeAsync();

                                }
                            }
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });

I tried to set the child under User to the email but firebase wouldnt let me use some special characters in the key. Any suggestions to make the code more efficient would be appreciated. Or any key suggestions that would make querying easier would be great.

Thanks in advance

2
you can do one think 1) sign up and login based on email and password , already firebase providing this facility , it will much easier for you ! - iamkdblue
Well if you really want to have email id's as a key, one simple way to get around the special characters would be to encode the characters like how html encodes '<' to '&lt;' - Karan Modi
@kdblue i am doing that but i want to add additional information like age, bio interests... - Charbel Hanna
@KaranModi i guess that would cause a hassle but thank you! - Charbel Hanna
@CharbelHanna yea you can ! , its good way to do it ! - iamkdblue

2 Answers

1
votes

Instead of putting random value or auto generated key you can add user's id which is received from fire base

firebaseAuth.getCurrentUser().getUid()

This will be more easy to access and will be more efficient because whenever you get will logged in, you will have this user_id and corresponding to user_id you can get email instead of checking all values in database

0
votes

The only way to retrieve email if you dont know the random key is this:

FirebaseDatabase database = FirebaseDatabase.getInstance();
                DatabaseReference ref = database.getReference("User");

                ref.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                   public void onDataChange(DataSnapshot dataSnapshot) {
                       for(DataSnapshot datas: dataSnapshot.getChildren()){                            for (DataSnapshot child:children) {
                            String email=datas.child("email").getValue().toString();
                   } 
                }
                     @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });

Or you can use firebase authentication and add the userid under Users instead of push() then retrieve the userid :

FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String userid=user.getUid();
FirebaseDatabase database = FirebaseDatabase.getInstance();
            DatabaseReference ref = database.getReference("User");

            ref.child(userid).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
               public void onDataChange(DataSnapshot dataSnapshot) {
                 String email=dataSnapshot.child("email").getValue().toString();
               } 
            }
                 @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

That way you do not have to loop.