Skip to content
Advertisement

When uploading a image for one user to firebase storage, the link of the image updates for every user in database

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.

Advertisement

Answer

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.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement