Ali*_*ira 5 android firebase-storage google-cloud-firestore android-workmanager
我正在寻找一种将数据上传到 Firebase 的解决方案,而无需用户等待数据上传,以便用户可以在离线模式下使用该应用程序。
我们假设该应用程序是关于地点的。在此应用程序中,用户可以上传图像和包含地址、城市、州、国家、纬度、经度、描述等的对象。假设是一个大 POJO。
Firebase 实时数据库和 Firebase Firestore 可以等待(我不知道多久)稳定的互联网连接来发送数据。但Firebase Storage没有这个功能。
所以我找到了WorkManager。它似乎解决了问题,但我必须将 POJO 序列化为小的原始变量类型才能将 POJO 发送到Worker类。
我想要达到的结果是:
1)将图像上传到Firebase存储
2) 图片的下载地址
3) 将 POJO 发送到 Firebase Firestore,其中包含 ImageUrl。
问题
1)WorkManager最适合这种目的吗?
2) 在离线模式下,用户可以触发此后台作业多少次而不会对应用程序造成任何问题?
3)如何正确地将POJO发送到班级Worker?
这是我到目前为止所做的:
获取新地点的 PushKey,启动后台作业并继续浏览活动:
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);
}
});
Run Code Online (Sandbox Code Playgroud)
设置后台作业的请求:
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();
}
Run Code Online (Sandbox Code Playgroud)
以下是Worker课程:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我很感激任何帮助!
| 归档时间: |
|
| 查看次数: |
1547 次 |
| 最近记录: |