安卓Firebase如何在注册到数据库之前等待图像上传



我是android开发的新手,遇到了一个问题。

我有一个片段,用户可以在其中发布公告,并且应该能够上传照片(可选(。当表格已满;发布公告";按钮时,我触发将信息保存到数据库的方法。

我面临的唯一问题是检索新上传照片的Uri。这是提取信息的代码。

public Map<String, Object> appendDataFromAnnouncementForm(){
String title = titleLineEdit.getText().toString();
String category = categoryLineEdit.getText().toString();
String description = descriptionLineEdit.getText().toString();
String date = dateLineEdit.getText().toString();
String time = timeLineEdit.getText().toString();
String location = locationLineEdit.getText().toString();
//Image upload to firebase + getting the Uri
if(localPhotoUri != null){
uploadImageToFirebase(generatePhotoName(localPhotoUri), localPhotoUri);
}

Map<String, Object> newAnnouncement = new HashMap<>();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
if(uploadedImageUri != null) // <- this is always null
{newAnnouncement.put("imageUri", uploadedImageUri.toString());}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
newAnnouncement.put("title", title);
newAnnouncement.put("category", category);
newAnnouncement.put("description", description);
newAnnouncement.put("date", date);
newAnnouncement.put("time", time);
newAnnouncement.put("location", location);

return newAnnouncement;
}

下面我发布了将照片上传到Firebase Storage的代码。自

private void uploadImageToFirebase(String photoName, Uri localContentUri) {
imagesStorageReferance = myStorageReference.child("images/" + photoName);
imagesStorageReferance.putFile(localContentUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//getUploadedImageUri(referenceToImageFolder);
imagesStorageReferance.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
Log.d(TAG, "onSuccess: The download url of the photo is "
+ uri.toString());
uploadedImageUri = uri; /// <- I want to retrieve this 
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: Failed uploading the photo to the database " + e.getMessage());
}
});
}

从我在互联网上看到的情况来看,这是一个同步问题(基本上,在我的照片上传之前,应用程序会将信息注册到数据库中(。我尝试过很多解决方案,但我真的找不到一个来解决我的案子。。。

如果你能给我解释一下我应该怎么做才能解决这个问题,我将不胜感激。如何等待照片上传?

我正在共享我的项目中的代码:

全局分配:

StorageTask uploadTask;
String myUrl = "";

这是代码:

private void uploadImage()
{
if (imageUri != null)
{
final StorageReference reference = storageReference.child(System.currentTimeMillis()+"."+getExtension(imageUri));
uploadTask = reference.putFile(imageUri);
uploadTask.continueWithTask(new Continuation() {
@Override
public Object then(@NonNull Task task) throws Exception {
if (!task.isComplete())
{
throw task.getException();
}
return reference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if (task.isSuccessful())
{
Uri downloadUri = task.getResult();
myUrl = downloadUri.toString();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Categories")
.child(randomKey);
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("categoryId", randomKey);
hashMap.put("categoryImage", myUrl);
hashMap.put("categoryName", editText.getText().toString());
databaseReference.setValue(hashMap);
save.setVisibility(View.VISIBLE);
startActivity(new Intent(AddCategoryActivity.this, CategoriesActivity.class));
}
else
{
save.setVisibility(View.VISIBLE);
Toast.makeText(AddCategoryActivity.this, "Failed!", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
save.setVisibility(View.VISIBLE);
Toast.makeText(AddCategoryActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
else
{
save.setVisibility(View.VISIBLE);
Toast.makeText(this, "No Image Selected", Toast.LENGTH_SHORT).show();
}
}

由于firebase是异步工作的,因此无论firebase是否完成上传过程,代码都会继续执行。在您的情况下,运行firebase后面的代码的时间比上传到firebase以最终分配uploadedImageUri = uri;的时间要快,这解释了为什么在调用上传后直接出现uploadedImageUri的空值。

对于这个问题,我建议您在uploadedImageUri = uri;之后注册到uploadImageToFirebase函数内的数据库,以确保uploadedImageUri从不为空,并且总是在数据库注册之前提取。

private void uploadImageToFirebase(String photoName, Uri localContentUri) {
imagesStorageReferance = myStorageReference.child("images/" + photoName);
imagesStorageReferance.putFile(localContentUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//getUploadedImageUri(referenceToImageFolder);
imagesStorageReferance.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
Log.d(TAG, "onSuccess: The download url of the photo is "
+ uri.toString());
uploadedImageUri = uri;
String title = titleLineEdit.getText().toString();
String category = categoryLineEdit.getText().toString();
String description = descriptionLineEdit.getText().toString();
String date = dateLineEdit.getText().toString();
String time = timeLineEdit.getText().toString();
String location = locationLineEdit.getText().toString();
Map<String, Object> newAnnouncement = new HashMap<>();
newAnnouncement.put("imageUri", uploadedImageUri.toString());
newAnnouncement.put("title", title);
newAnnouncement.put("category", category);
newAnnouncement.put("description", description);
newAnnouncement.put("date", date);
newAnnouncement.put("time", time);
newAnnouncement.put("location", location);
//UPLOAD newAnouncement TO FIREBASE HERE...
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: Failed uploading the photo to the database " + e.getMessage());
}
});
}

最新更新