1

I'm creating this app in Android Studio using Firebase Realtime Database and Firebase Storage. When a user registers through my app the data will store in the Firebase Realtime Database. Then on the profile page, there is a place to upload a picture. When a user uploads a picture it will store in the firebase storage and the link will update in the database on a new field under the respective user.

It worked correctly the last time I checked. But when I added a new user and uploaded his profile picture, that link updates on every other user as well. But in the Firebase Storage, there were no changes. It only happens in Firebase Realtime Database. I couldn't find any solution to this.

This is the part I update the link of the profile.

  

      private void UploadProfPic(Uri image_uri) {
    
            final StorageReference strRef = storageReference.child("users/"+ email_i +"/profile.jpg");
            strRef.putFile(image_uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    Toast.makeText(getApplicationContext(), "Image has been uploaded", Toast.LENGTH_LONG).show();
                    strRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                        @Override
                        public void onSuccess(Uri uri) {
                            Picasso.get().load(uri).fit().into(profPic);
    
    
                            imgRef = uri.toString();
    
    
                            usrRF.addValueEventListener(new ValueEventListener() {
                                @Override
                                public void onDataChange(@NonNull DataSnapshot snapshot) {
                                    for(DataSnapshot dss : snapshot.getChildren()){
                                        String key = dss.getKey();
    
                                        Map<String, Object> updates = new HashMap<String, Object>();
                                        updates.put("profile_url", imgRef);
                                        usrRF.child(key).updateChildren(updates);
    
                                    }
                                }
    
                                @Override
                                public void onCancelled(@NonNull DatabaseError error) {
    
                                    Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_LONG).show();
                                }
                            });
    
                        }
                    });
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull /*@org.jetbrains.annotations.NotNull*/ Exception e) {
                    Toast.makeText(getApplicationContext(), "Failed to update profile picture", Toast.LENGTH_LONG).show();
                }
            });
        }

here usrRf = FirebaseDatabase.getInstance().getReference("users");

Here is my database structure

Any help will be appreciated. Thank you.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Shehara_r
  • 17
  • 6
  • You say *that link updates on every other users as well* and as I understand you don't want that. In that case, which user would you like to get updated? In your screenshot, I see three users. – Alex Mamo Jul 20 '21 at 05:08
  • I want that url to be uploaded to that respective user who uploads the picture. in that screenshot, if cristiano uploads the picture, that url should be updated under his uid. The problem is that, when the picture has been uploaded, the url get updated for every other users as well. @AlexMamo – Shehara_r Jul 20 '21 at 05:32
  • Ok, fair enough. Are you using Firebase Authentication? – Alex Mamo Jul 20 '21 at 05:33
  • Yes, firebase email Authentication.. @AlexMamo – Shehara_r Jul 20 '21 at 05:39

1 Answers1

0

According to your last comment:

Yes, Firebase email Authentication

Then you should consider saving user data, under the UID that comes from the authentication process and not under a pushed ID, as I see in your screenshot now. This means that you should add a User object to the database using:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
usersRef.child(uid).setValue(userObj).addOnCompleteListener(/* ... /*);

And not using:

usersRef.push().setValue(userObj).addOnCompleteListener(/* ... /*);

That beeing said, to be able to update the image that is uploaded to the node of the logged-in user, then please use the following updated method:

final StorageReference strRef = storageReference.child("users/"+ email_i +"/profile.jpg");
strRef.putFile(image_uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
        Toast.makeText(getApplicationContext(), "Image has been uploaded", Toast.LENGTH_LONG).show();
        strRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                Picasso.get().load(uri).fit().into(profPic);
                imgRef = uri.toString();

                String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
                DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
                DatabaseReference usersRef = rootRef.child("users");
                Map<String, Object> updates = new HashMap<String, Object>();
                updates.put("profile_url", imgRef);
                usersRef.child(uid).updateChildren(updates).addOnSuccessListener(/* ... /*);
            }
        });
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull /*@org.jetbrains.annotations.NotNull*/ Exception e) {
        Toast.makeText(getApplicationContext(), "Failed to update profile picture", Toast.LENGTH_LONG).show();
    }
});

See, there is no for-loop involed? That was causing you trouble, as it was updating all child under "users" node.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thank you for the answer. I tried it using this authentication UID you mentioned before i tried this one i posted. When i tried to get that authentication uid , the app crashes everytime and given null pointer exception from android studio. Thats why i pushed a key at first place. But i will try again as you said and will let you know @AlexMamo – Shehara_r Jul 20 '21 at 06:18
  • If you got NullPointerException, most likely your user wasn't signed in. Check the CirebaseUser object against nullity. This [answer](https://stackoverflow.com/questions/50885891/one-time-login-in-app-firebaseauth) might also help. Yes, give it a try and tell me if it works. – Alex Mamo Jul 20 '21 at 06:26
  • I tried the way you said and it worked. Thank you for your help. but sorry i can't upvote your answer since i am new and don't have enough reputation for that @AlexMamo – Shehara_r Jul 20 '21 at 08:24