Skip to content

Commit

Permalink
fix(storage, android): correctly catch native exceptions for Promise.…
Browse files Browse the repository at this point in the history
…reject

Previously if you sent undefined in as a URL, or a URL that was unparseable,
the native android code would throw IllegalArgumentException, which would crash
the app with a native exception. Now those exceptions are caught and bubbled up
to the javascript layer correctly as a promise rejection

Fixes #4097
  • Loading branch information
mikehardy committed May 18, 2021
1 parent 7a4f78e commit 59e0669
Showing 1 changed file with 120 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,81 +61,101 @@ public void onCatalystInstanceDestroy() {
*/
@ReactMethod
public void delete(String appName, String url, final Promise promise) {
StorageReference reference = getReferenceFromUrl(url, appName);
reference.delete().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
promise.resolve(null);
} else {
promiseRejectStorageException(promise, Objects.requireNonNull(task.getException()));
}
});
try {
StorageReference reference = getReferenceFromUrl(url, appName);
reference.delete().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
promise.resolve(null);
} else {
promiseRejectStorageException(promise, Objects.requireNonNull(task.getException()));
}
});
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL
*/
@ReactMethod
public void getDownloadURL(String appName, final String url, final Promise promise) {
StorageReference reference = getReferenceFromUrl(url, appName);
Task<Uri> downloadTask = reference.getDownloadUrl();

downloadTask.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult() != null ? task.getResult().toString() : null);
} else {
promiseRejectStorageException(promise, task.getException());
}
});
try {
StorageReference reference = getReferenceFromUrl(url, appName);
Task<Uri> downloadTask = reference.getDownloadUrl();

downloadTask.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
promise.resolve(task.getResult() != null ? task.getResult().toString() : null);
} else {
promiseRejectStorageException(promise, task.getException());
}
});
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getMetadata
*/
@ReactMethod
public void getMetadata(String appName, String url, Promise promise) {
StorageReference reference = getReferenceFromUrl(url, appName);
reference.getMetadata().addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getMetadataAsMap(task.getResult()));
} else {
promiseRejectStorageException(promise, task.getException());
}
});
try {
StorageReference reference = getReferenceFromUrl(url, appName);
reference.getMetadata().addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getMetadataAsMap(task.getResult()));
} else {
promiseRejectStorageException(promise, task.getException());
}
});
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

@ReactMethod
public void list(String appName, String url, ReadableMap listOptions, Promise promise) {
StorageReference reference = getReferenceFromUrl(url, appName);
Task<ListResult> list;
try {
StorageReference reference = getReferenceFromUrl(url, appName);
Task<ListResult> list;

int maxResults = listOptions.getInt("maxResults");

if (listOptions.hasKey("pageToken")) {
String pageToken = listOptions.getString("pageToken");
list = reference.list(maxResults, Objects.requireNonNull(pageToken));
} else {
list = reference.list(maxResults);
}
int maxResults = listOptions.getInt("maxResults");

list.addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getListResultAsMap(task.getResult()));
if (listOptions.hasKey("pageToken")) {
String pageToken = listOptions.getString("pageToken");
list = reference.list(maxResults, Objects.requireNonNull(pageToken));
} else {
promiseRejectStorageException(promise, task.getException());
list = reference.list(maxResults);
}
});

list.addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getListResultAsMap(task.getResult()));
} else {
promiseRejectStorageException(promise, task.getException());
}
});
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

@ReactMethod
public void listAll(String appName, String url, Promise promise) {
StorageReference reference = getReferenceFromUrl(url, appName);
reference.listAll().addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getListResultAsMap(task.getResult()));
} else {
promiseRejectStorageException(promise, task.getException());
}
});
try {
StorageReference reference = getReferenceFromUrl(url, appName);
reference.listAll().addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getListResultAsMap(task.getResult()));
} else {
promiseRejectStorageException(promise, task.getException());
}
});
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

/**
Expand All @@ -148,16 +168,20 @@ public void updateMetadata(
ReadableMap metadataMap,
final Promise promise
) {
StorageReference reference = getReferenceFromUrl(url, appName);
StorageMetadata metadata = buildMetadataFromMap(metadataMap, null);

reference.updateMetadata(metadata).addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getMetadataAsMap(task.getResult()));
} else {
promiseRejectStorageException(promise, task.getException());
}
});
try {
StorageReference reference = getReferenceFromUrl(url, appName);
StorageMetadata metadata = buildMetadataFromMap(metadataMap, null);

reference.updateMetadata(metadata).addOnCompleteListener(getExecutor(), task -> {
if (task.isSuccessful()) {
promise.resolve(getMetadataAsMap(task.getResult()));
} else {
promiseRejectStorageException(promise, task.getException());
}
});
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

/**
Expand Down Expand Up @@ -214,15 +238,18 @@ public void writeToFile(
);
return;
}

StorageReference reference = getReferenceFromUrl(url, appName);
ReactNativeFirebaseStorageDownloadTask storageTask = new ReactNativeFirebaseStorageDownloadTask(
taskId,
reference,
appName
);
storageTask.begin(getTransactionalExecutor(), localFilePath);
storageTask.addOnCompleteListener(getTransactionalExecutor(), promise);
try {
StorageReference reference = getReferenceFromUrl(url, appName);
ReactNativeFirebaseStorageDownloadTask storageTask = new ReactNativeFirebaseStorageDownloadTask(
taskId,
reference,
appName
);
storageTask.begin(getTransactionalExecutor(), localFilePath);
storageTask.addOnCompleteListener(getTransactionalExecutor(), promise);
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

/**
Expand All @@ -238,14 +265,18 @@ public void putString(
int taskId,
Promise promise
) {
StorageReference reference = getReferenceFromUrl(url, appName);
ReactNativeFirebaseStorageUploadTask storageTask = new ReactNativeFirebaseStorageUploadTask(
taskId,
reference,
appName
);
storageTask.begin(getTransactionalExecutor(), string, format, metadataMap);
storageTask.addOnCompleteListener(getTransactionalExecutor(),promise);
try {
StorageReference reference = getReferenceFromUrl(url, appName);
ReactNativeFirebaseStorageUploadTask storageTask = new ReactNativeFirebaseStorageUploadTask(
taskId,
reference,
appName
);
storageTask.begin(getTransactionalExecutor(), string, format, metadataMap);
storageTask.addOnCompleteListener(getTransactionalExecutor(),promise);
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

/**
Expand All @@ -260,14 +291,18 @@ public void putFile(
int taskId,
Promise promise
) {
StorageReference reference = getReferenceFromUrl(url, appName);
ReactNativeFirebaseStorageUploadTask storageTask = new ReactNativeFirebaseStorageUploadTask(
taskId,
reference,
appName
);
storageTask.begin(getTransactionalExecutor(),localFilePath, metadata);
storageTask.addOnCompleteListener(getTransactionalExecutor(), promise);
try {
StorageReference reference = getReferenceFromUrl(url, appName);
ReactNativeFirebaseStorageUploadTask storageTask = new ReactNativeFirebaseStorageUploadTask(
taskId,
reference,
appName
);
storageTask.begin(getTransactionalExecutor(),localFilePath, metadata);
storageTask.addOnCompleteListener(getTransactionalExecutor(), promise);
} catch (Exception e) {
promiseRejectStorageException(promise, e);
}
}

@ReactMethod
Expand All @@ -290,7 +325,7 @@ private String getBucketFromUrl(String url) {
return url.substring(0, pathWithBucketName.indexOf("/") + 5);
}

private StorageReference getReferenceFromUrl(String url, String appName) {
private StorageReference getReferenceFromUrl(String url, String appName) throws IllegalArgumentException {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseStorage firebaseStorage = FirebaseStorage.getInstance(
firebaseApp,
Expand Down

0 comments on commit 59e0669

Please sign in to comment.