Skip to content

Commit 2b90c0b

Browse files
committed
1 parent 963d6d3 commit 2b90c0b

File tree

1 file changed

+151
-18
lines changed

1 file changed

+151
-18
lines changed

android/src/main/java/io/fullstack/firestack/storage/FirestackStorage.java

+151-18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import android.os.Environment;
55

66
import java.io.File;
7+
import java.io.FileOutputStream;
8+
import java.io.IOException;
9+
import java.io.InputStream;
710
import java.util.Map;
811
import java.util.HashMap;
912

@@ -17,13 +20,16 @@
1720
import com.facebook.react.bridge.WritableMap;
1821
import com.facebook.react.bridge.ReactMethod;
1922
import com.facebook.react.bridge.ReadableMap;
23+
import com.facebook.react.bridge.ReactContext;
2024
import com.facebook.react.bridge.ReactApplicationContext;
2125
import com.facebook.react.bridge.ReactContextBaseJavaModule;
2226

2327
import com.google.android.gms.tasks.Task;
2428
import com.google.android.gms.tasks.OnFailureListener;
2529
import com.google.android.gms.tasks.OnSuccessListener;
2630

31+
import com.google.firebase.storage.StorageException;
32+
import com.google.firebase.storage.StreamDownloadTask;
2733
import com.google.firebase.storage.UploadTask;
2834
import com.google.firebase.storage.FirebaseStorage;
2935
import com.google.firebase.storage.StorageMetadata;
@@ -49,6 +55,18 @@ public class FirestackStorage extends ReactContextBaseJavaModule {
4955
private static final String FileTypeRegular = "FILETYPE_REGULAR";
5056
private static final String FileTypeDirectory = "FILETYPE_DIRECTORY";
5157

58+
private static final String STORAGE_UPLOAD_PROGRESS = "upload_progress";
59+
private static final String STORAGE_UPLOAD_PAUSED = "upload_paused";
60+
private static final String STORAGE_UPLOAD_RESUMED = "upload_resumed";
61+
62+
private static final String STORAGE_DOWNLOAD_PROGRESS = "download_progress";
63+
private static final String STORAGE_DOWNLOAD_PAUSED = "download_paused";
64+
private static final String STORAGE_DOWNLOAD_RESUMED = "download_resumed";
65+
private static final String STORAGE_DOWNLOAD_SUCCESS = "download_success";
66+
private static final String STORAGE_DOWNLOAD_FAILURE = "download_failure";
67+
68+
private ReactContext mReactContext;
69+
5270
public FirestackStorage(ReactApplicationContext reactContext) {
5371
super(reactContext);
5472

@@ -60,14 +78,123 @@ public String getName() {
6078
return TAG;
6179
}
6280

81+
82+
public boolean isExternalStorageWritable() {
83+
String state = Environment.getExternalStorageState();
84+
return Environment.MEDIA_MOUNTED.equals(state);
85+
}
86+
87+
@ReactMethod
88+
public void downloadFile(final String urlStr,
89+
final String fbPath,
90+
final String localFile,
91+
final Callback callback) {
92+
Log.d(TAG, "downloadFile: " + urlStr + ", " + localFile);
93+
if (!isExternalStorageWritable()) {
94+
Log.w(TAG, "downloadFile failed: external storage not writable");
95+
WritableMap error = Arguments.createMap();
96+
final int errorCode = 1;
97+
error.putDouble("code", errorCode);
98+
error.putString("description", "downloadFile failed: external storage not writable");
99+
callback.invoke(error);
100+
return;
101+
}
102+
FirebaseStorage storage = FirebaseStorage.getInstance();
103+
String storageBucket = storage.getApp().getOptions().getStorageBucket();
104+
String storageUrl = "gs://" + storageBucket;
105+
Log.d(TAG, "Storage url " + storageUrl + fbPath);
106+
107+
StorageReference storageRef = storage.getReferenceFromUrl(storageUrl);
108+
StorageReference fileRef = storageRef.child(fbPath);
109+
110+
fileRef.getStream(new StreamDownloadTask.StreamProcessor() {
111+
@Override
112+
public void doInBackground(StreamDownloadTask.TaskSnapshot taskSnapshot, InputStream inputStream) throws IOException {
113+
int indexOfLastSlash = localFile.lastIndexOf("/");
114+
String pathMinusFileName = localFile.substring(0, indexOfLastSlash) + "/";
115+
String filename = localFile.substring(indexOfLastSlash + 1);
116+
File fileWithJustPath = new File(pathMinusFileName);
117+
if (!fileWithJustPath.mkdirs()) {
118+
Log.e(TAG, "Directory not created");
119+
WritableMap error = Arguments.createMap();
120+
error.putString("message", "Directory not created");
121+
callback.invoke(error);
122+
return;
123+
}
124+
File fileWithFullPath = new File(pathMinusFileName, filename);
125+
FileOutputStream output = new FileOutputStream(fileWithFullPath);
126+
int bufferSize = 1024;
127+
byte[] buffer = new byte[bufferSize];
128+
int len = 0;
129+
while ((len = inputStream.read(buffer)) != -1) {
130+
output.write(buffer, 0, len);
131+
}
132+
output.close();
133+
}
134+
}).addOnProgressListener(new OnProgressListener<StreamDownloadTask.TaskSnapshot>() {
135+
@Override
136+
public void onProgress(StreamDownloadTask.TaskSnapshot taskSnapshot) {
137+
WritableMap data = Arguments.createMap();
138+
data.putString("ref", taskSnapshot.getStorage().getBucket());
139+
double percentComplete = taskSnapshot.getTotalByteCount() == 0 ? 0.0f : 100.0f * (taskSnapshot.getBytesTransferred()) / (taskSnapshot.getTotalByteCount());
140+
data.putDouble("progress", percentComplete);
141+
Utils.sendEvent(mReactContext, STORAGE_DOWNLOAD_PROGRESS, data);
142+
}
143+
}).addOnPausedListener(new OnPausedListener<StreamDownloadTask.TaskSnapshot>() {
144+
@Override
145+
public void onPaused(StreamDownloadTask.TaskSnapshot taskSnapshot) {
146+
WritableMap data = Arguments.createMap();
147+
data.putString("ref", taskSnapshot.getStorage().getBucket());
148+
Utils.sendEvent(mReactContext, STORAGE_DOWNLOAD_PAUSED, data);
149+
}
150+
}).addOnSuccessListener(new OnSuccessListener<StreamDownloadTask.TaskSnapshot>() {
151+
@Override
152+
public void onSuccess(StreamDownloadTask.TaskSnapshot taskSnapshot) {
153+
final WritableMap data = Arguments.createMap();
154+
StorageReference ref = taskSnapshot.getStorage();
155+
data.putString("fullPath", ref.getPath());
156+
data.putString("bucket", ref.getBucket());
157+
data.putString("name", ref.getName());
158+
ref.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
159+
@Override
160+
public void onSuccess(final StorageMetadata storageMetadata) {
161+
data.putMap("metadata", getMetadataAsMap(storageMetadata));
162+
callback.invoke(null, data);
163+
}
164+
})
165+
.addOnFailureListener(new OnFailureListener() {
166+
@Override
167+
public void onFailure(@NonNull Exception exception) {
168+
final int errorCode = 1;
169+
WritableMap data = Arguments.createMap();
170+
StorageException storageException = StorageException.fromException(exception);
171+
data.putString("description", storageException.getMessage());
172+
data.putInt("code", errorCode);
173+
callback.invoke(makeErrorPayload(errorCode, exception));
174+
}
175+
});
176+
}
177+
}).addOnFailureListener(new OnFailureListener() {
178+
@Override
179+
public void onFailure(@NonNull Exception exception) {
180+
final int errorCode = 1;
181+
WritableMap data = Arguments.createMap();
182+
StorageException storageException = StorageException.fromException(exception);
183+
data.putString("description", storageException.getMessage());
184+
data.putInt("code", errorCode);
185+
callback.invoke(makeErrorPayload(errorCode, exception));
186+
}
187+
});
188+
}
189+
63190
@ReactMethod
64191
public void downloadUrl(final String javascriptStorageBucket,
65192
final String path,
66193
final Callback callback) {
67194
FirebaseStorage storage = FirebaseStorage.getInstance();
68195
String storageBucket = storage.getApp().getOptions().getStorageBucket();
69196
String storageUrl = "gs://" + storageBucket;
70-
Log.d(TAG, "FirestackStorage url " + storageUrl + path);
197+
Log.d(TAG, "Storage url " + storageUrl + path);
71198
final StorageReference storageRef = storage.getReferenceFromUrl(storageUrl);
72199
final StorageReference fileRef = storageRef.child(path);
73200

@@ -90,16 +217,7 @@ public void onSuccess(Uri uri) {
90217
public void onSuccess(final StorageMetadata storageMetadata) {
91218
Log.d(TAG, "getMetadata success " + storageMetadata);
92219

93-
WritableMap metadata = Arguments.createMap();
94-
metadata.putString("getBucket", storageMetadata.getBucket());
95-
metadata.putString("getName", storageMetadata.getName());
96-
metadata.putDouble("sizeBytes", storageMetadata.getSizeBytes());
97-
metadata.putDouble("created_at", storageMetadata.getCreationTimeMillis());
98-
metadata.putDouble("updated_at", storageMetadata.getUpdatedTimeMillis());
99-
metadata.putString("md5hash", storageMetadata.getMd5Hash());
100-
metadata.putString("encoding", storageMetadata.getContentEncoding());
101-
102-
res.putMap("metadata", metadata);
220+
res.putMap("metadata", getMetadataAsMap(storageMetadata));
103221
res.putString("name", storageMetadata.getName());
104222
res.putString("url", storageMetadata.getDownloadUrl().toString());
105223
callback.invoke(null, res);
@@ -109,7 +227,8 @@ public void onSuccess(final StorageMetadata storageMetadata) {
109227
@Override
110228
public void onFailure(@NonNull Exception exception) {
111229
Log.e(TAG, "Failure in download " + exception);
112-
callback.invoke(makeErrorPayload(1, exception));
230+
final int errorCode = 1;
231+
callback.invoke(makeErrorPayload(errorCode, exception));
113232
}
114233
});
115234

@@ -129,6 +248,18 @@ public void onFailure(@NonNull Exception exception) {
129248
});
130249
}
131250

251+
private WritableMap getMetadataAsMap(StorageMetadata storageMetadata) {
252+
WritableMap metadata = Arguments.createMap();
253+
metadata.putString("getBucket", storageMetadata.getBucket());
254+
metadata.putString("getName", storageMetadata.getName());
255+
metadata.putDouble("sizeBytes", storageMetadata.getSizeBytes());
256+
metadata.putDouble("created_at", storageMetadata.getCreationTimeMillis());
257+
metadata.putDouble("updated_at", storageMetadata.getUpdatedTimeMillis());
258+
metadata.putString("md5hash", storageMetadata.getMd5Hash());
259+
metadata.putString("encoding", storageMetadata.getContentEncoding());
260+
return metadata;
261+
}
262+
132263
// STORAGE
133264
@ReactMethod
134265
public void uploadFile(final String urlStr, final String name, final String filepath, final ReadableMap metadata, final Callback callback) {
@@ -191,9 +322,9 @@ public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
191322

192323
if (progress >= 0) {
193324
WritableMap data = Arguments.createMap();
194-
data.putString("eventName", "upload_progress");
325+
data.putString("eventName", STORAGE_UPLOAD_PROGRESS);
195326
data.putDouble("progress", progress);
196-
Utils.sendEvent(getReactApplicationContext(), "upload_progress", data);
327+
Utils.sendEvent(getReactApplicationContext(), STORAGE_UPLOAD_PROGRESS, data);
197328
}
198329
}
199330
})
@@ -204,13 +335,14 @@ public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
204335
StorageMetadata d = taskSnapshot.getMetadata();
205336
String bucket = d.getBucket();
206337
WritableMap data = Arguments.createMap();
207-
data.putString("eventName", "upload_paused");
338+
data.putString("eventName", STORAGE_UPLOAD_PAUSED);
208339
data.putString("ref", bucket);
209-
Utils.sendEvent(getReactApplicationContext(), "upload_paused", data);
340+
Utils.sendEvent(getReactApplicationContext(), STORAGE_UPLOAD_PAUSED, data);
210341
}
211342
});
212343
} catch (Exception ex) {
213-
callback.invoke(makeErrorPayload(2, ex));
344+
final int errorCode = 2;
345+
callback.invoke(makeErrorPayload(errorCode, ex));
214346
}
215347
}
216348

@@ -221,7 +353,8 @@ public void getRealPathFromURI(final String uri, final Callback callback) {
221353
callback.invoke(null, path);
222354
} catch (Exception ex) {
223355
ex.printStackTrace();
224-
callback.invoke(makeErrorPayload(1, ex));
356+
final int errorCode = 1;
357+
callback.invoke(makeErrorPayload(errorCode, ex));
225358
}
226359
}
227360

0 commit comments

Comments
 (0)