Android Studio:用于将数据上载到firebase的工人类
我正在寻找一种将数据上传到Firebase而不让用户等待数据上传的解决方案,以便用户可以在脱机模式下使用该应用程序 让我们假设这个应用程序是关于地点的。在这个应用程序中,用户可以上传一幅图像和一个包含地址、城市、州、国家、纬度、经度、描述等的对象。比如说一个大POJO Firebase实时数据库和Firebase Firestore可以等待(我不知道需要多长时间)稳定的互联网连接来发送数据。但是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
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;
}
}