Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f034c1f

Browse files
authored
Merge pull request #154 from devshackio/android-downloadFile
Implement storage.download() for Android
2 parents 7774ac1 + d50e976 commit f034c1f

File tree

2 files changed

+152
-535
lines changed

2 files changed

+152
-535
lines changed

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

Lines changed: 152 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import android.content.Context;
66

77
import java.io.File;
8+
import java.io.FileOutputStream;
9+
import java.io.IOException;
10+
import java.io.InputStream;
811
import java.util.Map;
912
import java.util.HashMap;
1013

@@ -26,6 +29,8 @@
2629
import com.google.android.gms.tasks.OnFailureListener;
2730
import com.google.android.gms.tasks.OnSuccessListener;
2831

32+
import com.google.firebase.storage.StorageException;
33+
import com.google.firebase.storage.StreamDownloadTask;
2934
import com.google.firebase.storage.UploadTask;
3035
import com.google.firebase.storage.FirebaseStorage;
3136
import com.google.firebase.storage.StorageMetadata;
@@ -49,6 +54,18 @@ class FirestackStorageModule extends ReactContextBaseJavaModule {
4954
private static final String FileTypeRegular = "FILETYPE_REGULAR";
5055
private static final String FileTypeDirectory = "FILETYPE_DIRECTORY";
5156

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

@@ -60,6 +77,118 @@ public String getName() {
6077
return TAG;
6178
}
6279

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

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);
222+
res.putMap("metadata", getMetadataAsMap(storageMetadata));
103223
res.putString("name", storageMetadata.getName());
104224
res.putString("url", storageMetadata.getDownloadUrl().toString());
105225
callback.invoke(null, res);
@@ -109,7 +229,8 @@ public void onSuccess(final StorageMetadata storageMetadata) {
109229
@Override
110230
public void onFailure(@NonNull Exception exception) {
111231
Log.e(TAG, "Failure in download " + exception);
112-
callback.invoke(makeErrorPayload(1, exception));
232+
final int errorCode = 1;
233+
callback.invoke(makeErrorPayload(errorCode, exception));
113234
}
114235
});
115236

@@ -129,6 +250,18 @@ public void onFailure(@NonNull Exception exception) {
129250
});
130251
}
131252

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

192325
if (progress >= 0) {
193326
WritableMap data = Arguments.createMap();
194-
data.putString("eventName", "upload_progress");
327+
data.putString("eventName", STORAGE_UPLOAD_PROGRESS);
195328
data.putDouble("progress", progress);
196-
FirestackUtils.sendEvent(getReactApplicationContext(), "upload_progress", data);
329+
FirestackUtils.sendEvent(getReactApplicationContext(), STORAGE_UPLOAD_PROGRESS, data);
197330
}
198331
}
199332
})
@@ -204,13 +337,14 @@ public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
204337
StorageMetadata d = taskSnapshot.getMetadata();
205338
String bucket = d.getBucket();
206339
WritableMap data = Arguments.createMap();
207-
data.putString("eventName", "upload_paused");
340+
data.putString("eventName", STORAGE_UPLOAD_PAUSED);
208341
data.putString("ref", bucket);
209-
FirestackUtils.sendEvent(getReactApplicationContext(), "upload_paused", data);
342+
FirestackUtils.sendEvent(getReactApplicationContext(), STORAGE_UPLOAD_PAUSED, data);
210343
}
211344
});
212345
} catch (Exception ex) {
213-
callback.invoke(makeErrorPayload(2, ex));
346+
final int errorCode = 2;
347+
callback.invoke(makeErrorPayload(errorCode, ex));
214348
}
215349
}
216350

@@ -221,7 +355,8 @@ public void getRealPathFromURI(final String uri, final Callback callback) {
221355
callback.invoke(null, path);
222356
} catch (Exception ex) {
223357
ex.printStackTrace();
224-
callback.invoke(makeErrorPayload(1, ex));
358+
final int errorCode = 1;
359+
callback.invoke(makeErrorPayload(errorCode, ex));
225360
}
226361
}
227362

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /