Android Studio:用于将数据上载到firebase的工人类

Android Studio:用于将数据上载到firebase的工人类,android,google-cloud-firestore,firebase-storage,android-workmanager,Android,Google Cloud Firestore,Firebase Storage,Android Workmanager,我正在寻找一种将数据上传到Firebase而不让用户等待数据上传的解决方案,以便用户可以在脱机模式下使用该应用程序 让我们假设这个应用程序是关于地点的。在这个应用程序中,用户可以上传一幅图像和一个包含地址、城市、州、国家、纬度、经度、描述等的对象。比如说一个大POJO Firebase实时数据库和Firebase Firestore可以等待(我不知道需要多长时间)稳定的互联网连接来发送数据。但是Firebase存储没有此功能 所以我找到了WorkManager。它似乎解决了这个问题,但我必须将P

我正在寻找一种将数据上传到Firebase而不让用户等待数据上传的解决方案,以便用户可以在脱机模式下使用该应用程序

让我们假设这个应用程序是关于地点的。在这个应用程序中,用户可以上传一幅图像和一个包含地址、城市、州、国家、纬度、经度、描述等的对象。比如说一个大POJO

Firebase实时数据库和Firebase Firestore可以等待(我不知道需要多长时间)稳定的互联网连接来发送数据。但是Firebase存储没有此功能

所以我找到了
WorkManager
。它似乎解决了这个问题,但我必须将POJO序列化为小的基本变量类型,以便将POJO发送到
Worker

我想要达到的结果是:

1) 将图像上载到Firebase存储

2) 下载图像的URL

3) 将POJO发送到Firebase Firestore,其中包含ImageUrl

问题

1)
WorkManager
最适合这种用途吗

2) 在脱机模式下,用户可以触发多少次此后台作业而不会对应用程序造成任何问题

3) 如何适当地将POJO发送到
工作者

以下是我迄今为止所做的工作:

获取新位置的快捷键,开始后台作业并在活动中导航:

    savePlaceData.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            DocumentReference docRef = DatabaseRouter.getPlaceCollectionRef().document();
            String key = docRef.getId();
            uploadPlaceDataInBackground(key)
            Intent intent = new Intent(PlaceActivity.this, OtherActivity.class);
            startActivity(intent);

        }
    });
设置后台作业的请求:

    private void uploadPlaceDataInBackground(String placeKey) {
        // TESTING WORKMANAGER FOR UPLOADING IMAGES TO FIREBASE STORAGE
        // Create a Constraints object that defines when the task should run
        Constraints constraints = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build();

        // Passing data to the worker class
        Data.Builder uploadBuilder = new Data.Builder();
        uploadBuilder.putString("image_uri", placeImageUri.toString());
        uploadBuilder.putString("image_pushkey", placeKey);
        Data ImageUriInputData = uploadBuilder.build();

        // ...then create a OneTimeWorkRequest that uses those constraints
        OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest
                .Builder(UploadImageWorker.class)
                .setConstraints(constraints)
                .setInputData(ImageUriInputData)
                .build();

        OneTimeWorkRequest downloadWorkRequest = new OneTimeWorkRequest
                .Builder(DownloadImageUrlWorker.class)
                .setConstraints(constraints)
                .build();

        // Converting placeObject into Map
        Data.Builder uploadPlaceBuilder = new Data.Builder();
        Map<String, Object> placeMap = convertPlaceObjectIntoMap();
        uploadPlaceBuilder.putAll(placeMap);
        Data placeInfoInputData = uploadPlaceBuilder.build();

        OneTimeWorkRequest uploadPlaceWorkRequest = new OneTimeWorkRequest
                .Builder(UploadPlaceWorker.class)
                .setConstraints(constraints)
                .setInputData(placeInfoInputData)
                .build();

        // Execute and Manage the background service
        WorkManager workManager = WorkManager.getInstance(getActivity());
        workManager.beginWith(uploadWorkRequest)
                .then(downloadWorkRequest)
                .then(uploadPlaceWorkRequest)
                .enqueue();
    }
谢谢你的帮助

public class UploadImageWorker extends Worker {

    public UploadImageWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        String imageUriInput = getInputData().getString("image_uri");
        String imagePushKey = getInputData().getString("image_pushkey");

        final Result[] result = {Result.retry()};
        CountDownLatch countDownLatch = new CountDownLatch(1);
        StorageReference storageRef = DatabaseRouter.getPlaceStorageRef(imagePushKey).child(imagePushKey+".jpg");
        storageRef.putFile(Uri.parse(imageUriInput)).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                if (task.isSuccessful()) {
                    result[0] = Result.success(getInputData());
                } else {
                    Log.i(TAG, "onComplete: image NOT uploaded - RETRYING");
                    result[0] = Result.retry();
                }
                countDownLatch.countDown();
            }
        });

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result[0];
    }
}

public class DownloadImageUrlWorker extends Worker {

    public DownloadImageUrlWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        String imageUriInput = getInputData().getString("image_uri");
        String imagePushKey = getInputData().getString("image_pushkey");

        final Result[] result = {Result.retry()};
        CountDownLatch countDownLatch = new CountDownLatch(1);
        StorageReference storageRef = DatabaseRouter.getPlaceStorageRef(imagePushKey).child(imagePushKey+".jpg");
        storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                String imageUrl = uri.toString();

                Data.Builder outputBuilder = new Data.Builder();
                outputBuilder.putString("image_url", imageUrl);
                outputBuilder.putString("image_pushkey", imagePushKey);
                Data outputData = outputBuilder.build();
                result[0] = Result.success(outputData);

                countDownLatch.countDown();
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.i(TAG, "onFailure: imageUrl NOT downloaded - RETRYING");
                result[0] = Result.retry();
                countDownLatch.countDown();
            }
        });



        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result[0];
    }
}

public class UploadPlaceWorker extends Worker {

    public UploadPlaceWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        String imageUrl = getInputData().getString("image_url");
        String imagePushKey = getInputData().getString("image_pushkey");

        Map<String, Object> placeObject = getInputData().getKeyValueMap();

        PlaceModel placeModel = convertMapIntoPlaceObject(placeObject, imageUrl, imagePushKey);

        final Result[] result = {Result.retry()};
        CountDownLatch countDownLatch = new CountDownLatch(1);
        DocumentReference docRef = DatabaseRouter.getPlaceCollectionRef().document(imagePushKey);
        docRef.set(placeModel).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    result[0] = Result.success();
                } else {
                    Log.i(TAG, "onComplete: place NOT uploaded - RETRYING");
                    result[0] = Result.retry();
                }
                countDownLatch.countDown();
            }
        });

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return result[0];
    }

    private PlaceModel convertMapIntoPlaceObject(Map<String, Object> placeMap, String imageUrl, String placeKey) {
        PlaceModel place = new PlaceModel();
        place.setAddress(placeMap.get("a").toString());
        place.setCity(placeMap.get("b").toString());
        place.setCountry(placeMap.get("c").toString());
        place.setDistrict(placeMap.get("d").toString());
        place.setG(placeMap.get("e").toString());
        place.setId(placeMap.get("f").toString());
        place.setImage(imageUrl);
        place.setKey(placeKey);
        GeoPoint geoPoint = new GeoPoint((Double) placeMap.get("h"), (Double) placeMap.get("i"));
        place.setL(geoPoint);
        place.setDescription(placeMap.get("j").toString());

        return place;
    }
}