简体   繁体   English

如何在Android上优先处理Firebase查询

[英]How to Prioritize Firebase queries on Android

As I'm going through Firebase Storage and Database tutorials for Android, I came across to a problem to prioritize the queries. 在浏览Android的Firebase存储和数据库教程时,遇到了一个问题,需要对查询进行优先级排序。

I need to save a visitor data into Firestore Database and an image of a visitor in the Firebase Storage with a single button click. 我需要通过单击一下按钮将访问者数据保存到Firestore Database ,并将访问者的图像保存到Firebase Storage So, I have the following java method in Android: 因此,我在Android中具有以下java方法:

public void saveNewVisitor() {
    Uri file = Uri.fromFile(new File(image_path));
    StorageReference imageRef = storageRef.child("images/"+file.getLastPathSegment());
    UploadTask uploadTask = imageRef.putFile(file);

    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle unsuccessful uploads
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            downloadURL = taskSnapshot.getDownloadUrl();
        }
    });
//-----------------------------------
    Map<String, Object> dataToSave = new HashMap<String, Object>();
    dataToSave.put(NAME, visitorName);
    dataToSave.put(AGE, visitorAge);
    dataToSave.put(GENDER, visitorGender);
    dataToSave.put(IMAGE_URL, String.valueOf(downloadURL));

    CollectionReference mColRef = FirebaseFirestore.getInstance().collection("visitors");
    mColRef.add(dataToSave).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
        @Override
        public void onSuccess(DocumentReference documentReference) {
            Log.d(TAG, "Visitor has been saved!");
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.w(TAG, "Error adding a visitor", e);
        }
    });
}

In the above code, there are two actions happening. 在上面的代码中,发生了两个动作。 In the first part, an image is being saved in Firebase Storage and in OnSuccessListener it's generating URL to download that image for the future use. 在第一部分中,图像被保存在火力地堡贮存和OnSuccessListener它生成URL下载该图片为将来使用。 In the second part, the text data, including above generated URL is being saved in the Database. 在第二部分中,包含上面生成的URL的文本数据被保存在数据库中。

So, the problem is, Android and Firebase is executing text data query first, then executing image saving query. 因此,问题在于,Android和Firebase首先执行文本数据查询,然后执行图像保存查询。 This is resulting in URL = null in database as at the time of saving the data downloadURL = null . 这导致在保存数据downloadURL = null时数据库中的URL = null downloadURL = null

My question is how to prioritize image saving query as HIGH to make sure it'll be executed before text data saving query. 我的问题是如何将图像保存查询的优先级设置为“高”,以确保在文本数据保存查询之前将其执行。 Firebase documents aren't that clear on this topic. Firebase文档在此主题上不清楚。 Any kind of help or suggestion to resolve the problem is appreciated. 任何形式的帮助或建议,以解决该问题表示赞赏。

Uploading a file to Firebase using an UploadTask is performed asynchronously and therefore your upload task is still running and has not yet completed before you call mColRef.add(dataToSave) , which is also executed asynchronously. 使用UploadTask将文件上传到Firebase是异步执行的,因此,在调用mColRef.add(dataToSave)之前,您的上传任务仍在运行并且尚未完成,该操作也是异步执行的。

In order to chain both of these asynchronous methods, you'll need to move the second half of your method logic inside the onSuccess() block of your UploadTask . 为了链接这两个异步方法,您需要将方法逻辑的UploadTaskonSuccess()块内。 That way, your database operation is only performed once your upload task has completed, and you are guaranteed to have access to the download URL. 这样,您的数据库操作仅在上载任务完成后才执行,并且可以保证您可以访问下载URL。

For a complete example, you could split the method into two parts so it's easier to see what's happening: 对于完整的示例,可以将方法分为两部分,以便更轻松地了解正在发生的情况:

public void saveNewVisitor() {
    Uri file = Uri.fromFile(new File(image_path));
    StorageReference imageRef = storageRef.child("images/"+file.getLastPathSegment());
    UploadTask uploadTask = imageRef.putFile(file);

    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle unsuccessful uploads
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            downloadURL = taskSnapshot.getDownloadUrl();
            saveNewVisitorToDatabase(String.valueOf(downloadURL));
        }
    });
}

private void saveNewVisitorToDatabase(String downloadURL) {
    Map<String, Object> dataToSave = new HashMap<String, Object>();
    dataToSave.put(NAME, visitorName);
    dataToSave.put(AGE, visitorAge);
    dataToSave.put(GENDER, visitorGender);
    dataToSave.put(IMAGE_URL, downloadURL);

    CollectionReference mColRef = FirebaseFirestore.getInstance().collection("visitors");
    mColRef.add(dataToSave).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
        @Override
        public void onSuccess(DocumentReference documentReference) {
            Log.d(TAG, "Visitor has been saved!");
            // Once we reach here, we can guarantee that the upload task
            // and this database operation were both successful
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.w(TAG, "Error adding a visitor", e);
        }
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM