0

I am developing a quiz application whereby a User takes a quiz and after 10 questions the score is saved to a database in Firebase.

Here is my code at present:

String user_id = mAuth.getCurrentUser().getUid();

        DatabaseReference current_user_db = 
FirebaseDatabase.getInstance().getReference().child("Score").child(user_id);

        final int score = mScore;

        **databaseUserName = FirebaseDatabase.getInstance().getReference().child("Users").child(user_id).child("username");
        databaseUserName.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
            @Override
            public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
                String username = dataSnapshot.getValue().toString();
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });**


        //Ensures everything saves at the same time
        Map newPost = new HashMap();
        newPost.put("Score", score);
        **newPost.put("Username", username);**

        current_user_db.setValue(newPost);

The part enclosed in ** ** is where I am having some difficulties.

The user signs up to my app using FirebaseAuth, then using the UID I have stored name and username in a 'Users' realtime database.

I would like the score databse to save the final score with the username not the autogenerated UID. I'm just not sure how to get the username and then save it to the new database.

I have also attached a screenshot of how my current database looks.

I have only been using Firebase and Android Studio a few weeks so any help/links are all appreciated.

enter image description here

divyanshu bhargava
  • 1,513
  • 1
  • 13
  • 24
coderob
  • 3
  • 1
  • 7

3 Answers3

0

You can do something like this

    final String userName = "userX";
    final int score = 55;
    FirebaseDatabase db = FirebaseDatabase.getInstance();
    db.getReference("Score").child(userName).child("Score").setValue(score).addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Log.d(TAG, "onSuccess: updated " + userName + "'s score (" + score + ")");
        }
    });
Omar Sahl
  • 76
  • 5
  • That is not referencing the current users username stored in the database though is it? – coderob Feb 04 '18 at 17:53
  • You retrieved the current username with this line `String username = dataSnapshot.getValue().toString();` right? – Omar Sahl Feb 04 '18 at 19:08
  • That was how I tried to do it but I kept getting errors when I tried to add the variable username to the new database – coderob Feb 04 '18 at 19:13
  • Just to make sure I'm getting it right, That userName you retrieved from the database is the one you want to use as a key to the score value right? – Omar Sahl Feb 04 '18 at 19:15
  • It was originally but then I realised you can not repeat keys, so now I have implemented the push function whereby a random key will be assigned. I would like the Username and Score to save inside that key, if that makes sense. The UID and username are different values. – coderob Feb 04 '18 at 19:23
0

Change your String userName to a member.

 String user_id = mAuth.getCurrentUser().getUid();

   // you can remove child(user_id) if you want to put username directly under Score
   DatabaseReference current_user_db = FirebaseDatabase.getInstance().getReference().child("Score").child(user_id); 

   final int score = mScore;

   DatabaseReference databaseUserName = FirebaseDatabase.getInstance().getReference().child("Users").child(user_id).child("username");
  databaseUserName.addValueEventListener(new ValueEventListener() {
       @Override
       public void onDataChange(DataSnapshot dataSnapshot) {
           userName = dataSnapshot.getValue().toString();
       }

       @Override
       public void onCancelled(DatabaseError databaseError) {

       }
   });

   //Ensures everything saves at the same time
   Map newPost = new HashMap();
   newPost.put("Score", score);
   newPost.put("Username", username); // I don't think you need this.

   current_user_db.child(username).setValue(newPost);

Let me know if it works.

notakoba
  • 160
  • 1
  • 13
0

There is no way in which you can simply use username outside onDataChange() method because this method has an asynchronous behaviour which means that is called even before you are trying to get the data from the database. A quick fix to you are problem would be to move the follwing lines of code:

Map newPost = new HashMap();
newPost.put("Score", score);
newPost.put("Username", username);
current_user_db.child(username).setValue(newPost);

Inside onDataChange() method and your problem will be solved but if you need to use the value of username outside the onDataChange() method, then you need to create your own callback and for that I recomend you see the last part of my answer from this post.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193