将一个用户的图像上传到 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 存储时,数据库中每个用户的图像链接都会更新的主要内容,如果未能解决你的问题,请参考以下文章
Flutter将图像上传到firebase存储然后将其写入firestore
当我尝试将图像上传到 Firebase 存储时,putFile 在 kotlin 中不起作用