5
5
import android .content .Context ;
6
6
7
7
import java .io .File ;
8
+ import java .io .FileOutputStream ;
9
+ import java .io .IOException ;
10
+ import java .io .InputStream ;
8
11
import java .util .Map ;
9
12
import java .util .HashMap ;
10
13
26
29
import com .google .android .gms .tasks .OnFailureListener ;
27
30
import com .google .android .gms .tasks .OnSuccessListener ;
28
31
32
+ import com .google .firebase .storage .StorageException ;
33
+ import com .google .firebase .storage .StreamDownloadTask ;
29
34
import com .google .firebase .storage .UploadTask ;
30
35
import com .google .firebase .storage .FirebaseStorage ;
31
36
import com .google .firebase .storage .StorageMetadata ;
@@ -49,6 +54,18 @@ class FirestackStorageModule extends ReactContextBaseJavaModule {
49
54
private static final String FileTypeRegular = "FILETYPE_REGULAR" ;
50
55
private static final String FileTypeDirectory = "FILETYPE_DIRECTORY" ;
51
56
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
+
52
69
public FirestackStorageModule (ReactApplicationContext reactContext ) {
53
70
super (reactContext );
54
71
@@ -60,6 +77,118 @@ public String getName() {
60
77
return TAG ;
61
78
}
62
79
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
+
63
192
@ ReactMethod
64
193
public void downloadUrl (final String javascriptStorageBucket ,
65
194
final String path ,
@@ -90,16 +219,7 @@ public void onSuccess(Uri uri) {
90
219
public void onSuccess (final StorageMetadata storageMetadata ) {
91
220
Log .d (TAG , "getMetadata success " + storageMetadata );
92
221
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 ));
103
223
res .putString ("name" , storageMetadata .getName ());
104
224
res .putString ("url" , storageMetadata .getDownloadUrl ().toString ());
105
225
callback .invoke (null , res );
@@ -109,7 +229,8 @@ public void onSuccess(final StorageMetadata storageMetadata) {
109
229
@ Override
110
230
public void onFailure (@ NonNull Exception exception ) {
111
231
Log .e (TAG , "Failure in download " + exception );
112
- callback .invoke (makeErrorPayload (1 , exception ));
232
+ final int errorCode = 1 ;
233
+ callback .invoke (makeErrorPayload (errorCode , exception ));
113
234
}
114
235
});
115
236
@@ -129,6 +250,18 @@ public void onFailure(@NonNull Exception exception) {
129
250
});
130
251
}
131
252
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
+
132
265
// STORAGE
133
266
@ ReactMethod
134
267
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) {
191
324
192
325
if (progress >= 0 ) {
193
326
WritableMap data = Arguments .createMap ();
194
- data .putString ("eventName" , "upload_progress" );
327
+ data .putString ("eventName" , STORAGE_UPLOAD_PROGRESS );
195
328
data .putDouble ("progress" , progress );
196
- FirestackUtils .sendEvent (getReactApplicationContext (), "upload_progress" , data );
329
+ FirestackUtils .sendEvent (getReactApplicationContext (), STORAGE_UPLOAD_PROGRESS , data );
197
330
}
198
331
}
199
332
})
@@ -204,13 +337,14 @@ public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
204
337
StorageMetadata d = taskSnapshot .getMetadata ();
205
338
String bucket = d .getBucket ();
206
339
WritableMap data = Arguments .createMap ();
207
- data .putString ("eventName" , "upload_paused" );
340
+ data .putString ("eventName" , STORAGE_UPLOAD_PAUSED );
208
341
data .putString ("ref" , bucket );
209
- FirestackUtils .sendEvent (getReactApplicationContext (), "upload_paused" , data );
342
+ FirestackUtils .sendEvent (getReactApplicationContext (), STORAGE_UPLOAD_PAUSED , data );
210
343
}
211
344
});
212
345
} catch (Exception ex ) {
213
- callback .invoke (makeErrorPayload (2 , ex ));
346
+ final int errorCode = 2 ;
347
+ callback .invoke (makeErrorPayload (errorCode , ex ));
214
348
}
215
349
}
216
350
@@ -221,7 +355,8 @@ public void getRealPathFromURI(final String uri, final Callback callback) {
221
355
callback .invoke (null , path );
222
356
} catch (Exception ex ) {
223
357
ex .printStackTrace ();
224
- callback .invoke (makeErrorPayload (1 , ex ));
358
+ final int errorCode = 1 ;
359
+ callback .invoke (makeErrorPayload (errorCode , ex ));
225
360
}
226
361
}
227
362
0 commit comments