将一个用户的图像上传到 Firebase 存储时,数据库中每个用户的图像链接都会更新

Posted

技术标签:

【中文标题】将一个用户的图像上传到 Firebase 存储时,数据库中每个用户的图像链接都会更新【英文标题】:When uploading a image for one user to firebase storage, the link of the image updates for every user in database 【发布时间】:2021-09-27 07:59:48 【问题描述】:

我正在使用 Firebase 实时数据库和 Firebase 存储在 android Studio 中创建这个应用程序。当用户通过我的应用注册时,数据将存储在 Firebase 实时数据库中。然后在个人资料页面上,有一个上传图片的地方。当用户上传图片时,它将存储在 Firebase 存储中,并且链接将在数据库中相应用户下的新字段中更新。

我上次检查时它工作正常。但是当我添加一个新用户并上传他的个人资料图片时,该链接也会在所有其他用户上更新。但在 Firebase 存储中,没有任何变化。它只发生在 Firebase 实时数据库中。我找不到任何解决方案。

这是我更新个人资料链接的部分。

  

      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();
                
            );
        

这里 usrRf = FirebaseDatabase.getInstance().getReference("users");

Here is my database structure

任何帮助将不胜感激。谢谢。

【问题讨论】:

您说其他用户的链接也会更新,据我了解,您不希望这样。在这种情况下,您希望更新哪个用户?在您的屏幕截图中,我看到了三个用户。 我希望将该网址上传给上传图片的相应用户。在该屏幕截图中,如果克里斯蒂亚诺上传了图片,则该 url 应该在他的 uid 下更新。问题是,当图片上传后,所有其他用户的 url 也会更新。 @AlexMamo 好的,很公平。你在使用 Firebase 身份验证吗? 是的,firebase 电子邮件身份验证.. @AlexMamo 【参考方案1】:

根据你上一条评论:

是的,Firebase 电子邮件身份验证

那么您应该考虑将用户数据保存在来自身份验证过程的 UID 下,而 保存在推送的 ID 下,正如我现在在您的 screenshot 中看到的那样。这意味着您应该使用以下方法将用户对象添加到数据库:

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

并且使用:

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

也就是说,要更新上传到登录用户节点的图片,请使用以下更新方法:

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();
    
);

看,有没有涉及到for循环?这给您带来了麻烦,因为它正在更新“用户”节点下的所有子节点。

【讨论】:

感谢您的回答。在我尝试发布的这个之前,我使用你提到的这个身份验证 UID 进行了尝试。当我尝试获取该身份验证 uid 时,应用程序每次都崩溃并从 android studio 给出空指针异常。这就是为什么我首先按了一个键。但我会按照你说的再试一次,并让你知道@AlexMamo 如果您得到 NullPointerException,很可能您的用户没有登录。检查 CirebaseUser 对象是否为空。这个answer 也可能有帮助。是的,试一试,告诉我它是否有效。 我试过你说的方法,效果很好。谢谢您的帮助。但很抱歉,我不能赞成你的回答,因为我是新手,对@AlexMamo 没有足够的声誉 不客气,Shehara_r。不用担心,当你有足够的声誉时,你可以投票。

以上是关于将一个用户的图像上传到 Firebase 存储时,数据库中每个用户的图像链接都会更新的主要内容,如果未能解决你的问题,请参考以下文章

将图像上传到 Firebase 存储时如何制作进度条?

Flutter将图像上传到firebase存储然后将其写入firestore

当我尝试将图像上传到 Firebase 存储时,putFile 在 kotlin 中不起作用

尽管没有引发错误,但图像似乎没有上传到 Firebase 存储

尝试将图像上传到 Firebase 存储时出错

将图像上传到 Firebase 存储后如何获取图像 uri?