@@ -52,15 +52,15 @@ @implementation FirestackStorage
5252 [err setValue: @" Call setStorageUrl() first" forKey: @" description" ];
5353 return callback (@[err]);
5454 }
55-
55+
5656 if ([path hasPrefix: @" assets-library://" ]) {
5757 NSURL *localFile = [[NSURL alloc ] initWithString: path];
5858 PHFetchResult* assets = [PHAsset fetchAssetsWithALAssetURLs: @[localFile] options: nil ];
5959 PHAsset *asset = [assets firstObject ];
6060 [asset requestContentEditingInputWithOptions: nil
6161 completionHandler: ^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
6262 NSURL *imageFile = contentEditingInput.fullSizeImageURL ;
63-
63+
6464 [self performUpload: urlStr
6565 name: name
6666 file: imageFile
@@ -70,14 +70,14 @@ @implementation FirestackStorage
7070 } else {
7171 NSURL *localFile = [NSURL fileURLWithPath: path];
7272 FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc ] initWithDictionary: metadata];
73-
73+
7474 [self performUpload: urlStr
7575 name: name
7676 file: localFile
7777 metadata: firmetadata
7878 callback: callback];
7979 }
80-
80+
8181}
8282
8383- (void ) performUpload : (NSString *) urlStr
@@ -88,10 +88,10 @@ - (void) performUpload:(NSString *) urlStr
8888{
8989 FIRStorageReference *storageRef = [[FIRStorage storage ] referenceForURL: urlStr];
9090 FIRStorageReference *uploadRef = [storageRef child: name];
91-
91+
9292 FIRStorageUploadTask *uploadTask = [uploadRef putFile: imageFile
9393 metadata: firmetadata];
94-
94+
9595 // Listen for state changes, errors, and completion of the upload.
9696 [uploadTask observeStatus: FIRStorageTaskStatusResume handler: ^(FIRStorageTaskSnapshot *snapshot) {
9797 // Upload resumed, also fires when the upload starts
@@ -100,7 +100,7 @@ - (void) performUpload:(NSString *) urlStr
100100 @" ref" : snapshot.reference .bucket
101101 }];
102102 }];
103-
103+
104104 [uploadTask observeStatus: FIRStorageTaskStatusPause handler: ^(FIRStorageTaskSnapshot *snapshot) {
105105 // Upload paused
106106 [self sendJSEvent: STORAGE_UPLOAD_PAUSED props: @{
@@ -116,17 +116,17 @@ - (void) performUpload:(NSString *) urlStr
116116 } else {
117117 percentComplete = 100.0 * (snapshot.progress .completedUnitCount ) / (snapshot.progress .totalUnitCount );
118118 }
119-
119+
120120 [self sendJSEvent: STORAGE_UPLOAD_PROGRESS props: @{
121121 @" eventName" : STORAGE_UPLOAD_PROGRESS,
122122 @" progress" : @(percentComplete)
123123 }];
124-
124+
125125 }];
126-
126+
127127 [uploadTask observeStatus: FIRStorageTaskStatusSuccess handler: ^(FIRStorageTaskSnapshot *snapshot) {
128128 [uploadTask removeAllObservers ];
129-
129+
130130 // Upload completed successfully
131131 FIRStorageReference *ref = snapshot.reference ;
132132 NSDictionary *props = @{
@@ -135,14 +135,14 @@ - (void) performUpload:(NSString *) urlStr
135135 @" name" : ref.name ,
136136 @" metadata" : [snapshot.metadata dictionaryRepresentation ]
137137 };
138-
138+
139139 callback (@[[NSNull null ], props]);
140140 }];
141-
141+
142142 [uploadTask observeStatus: FIRStorageTaskStatusFailure handler: ^(FIRStorageTaskSnapshot *snapshot) {
143143 if (snapshot.error != nil ) {
144144 NSDictionary *errProps = [[NSMutableDictionary alloc ] init ];
145-
145+
146146 switch (snapshot.error .code ) {
147147 case FIRStorageErrorCodeObjectNotFound:
148148 // File doesn't exist
@@ -161,17 +161,112 @@ - (void) performUpload:(NSString *) urlStr
161161 [errProps setValue: @" Unknown error" forKey: @" description" ];
162162 break ;
163163 }
164-
164+
165+ callback (@[errProps]);
166+ }}];
167+ }
168+
169+ RCT_EXPORT_METHOD (downloadFile: (NSString *) urlStr
170+ path:(NSString *) path
171+ localFile:(NSString *) file
172+ callback:(RCTResponseSenderBlock) callback)
173+ {
174+ if (urlStr == nil ) {
175+ NSError *err = [[NSError alloc ] init ];
176+ [err setValue: @" Storage configuration error" forKey: @" name" ];
177+ [err setValue: @" Call setStorageUrl() first" forKey: @" description" ];
178+ return callback (@[err]);
179+ }
180+
181+ FIRStorageReference *storageRef = [[FIRStorage storage ] referenceForURL: urlStr];
182+ FIRStorageReference *fileRef = [storageRef child: path];
183+
184+ NSURL *localFile = [NSURL fileURLWithPath: file];
185+
186+ FIRStorageDownloadTask *downloadTask = [fileRef writeToFile: localFile];
187+ // Listen for state changes, errors, and completion of the download.
188+ [downloadTask observeStatus: FIRStorageTaskStatusResume handler: ^(FIRStorageTaskSnapshot *snapshot) {
189+ // Upload resumed, also fires when the upload starts
190+ [self sendJSEvent: STORAGE_DOWNLOAD_RESUMED props: @{
191+ @" eventName" : STORAGE_DOWNLOAD_RESUMED,
192+ @" ref" : snapshot.reference .bucket
193+ }];
194+ }];
195+
196+ [downloadTask observeStatus: FIRStorageTaskStatusPause handler: ^(FIRStorageTaskSnapshot *snapshot) {
197+ // Upload paused
198+ [self sendJSEvent: STORAGE_DOWNLOAD_PAUSED props: @{
199+ @" eventName" : STORAGE_DOWNLOAD_PAUSED,
200+ @" ref" : snapshot.reference .bucket
201+ }];
202+ }];
203+ [downloadTask observeStatus: FIRStorageTaskStatusProgress handler: ^(FIRStorageTaskSnapshot *snapshot) {
204+ // Upload reported progress
205+ float percentComplete;
206+ if (snapshot.progress .totalUnitCount == 0 ) {
207+ percentComplete = 0.0 ;
208+ } else {
209+ percentComplete = 100.0 * (snapshot.progress .completedUnitCount ) / (snapshot.progress .totalUnitCount );
210+ }
211+
212+ [self sendJSEvent: STORAGE_DOWNLOAD_PROGRESS props: @{
213+ @" eventName" : STORAGE_DOWNLOAD_PROGRESS,
214+ @" progress" : @(percentComplete)
215+ }];
216+
217+ }];
218+
219+ [downloadTask observeStatus: FIRStorageTaskStatusSuccess handler: ^(FIRStorageTaskSnapshot *snapshot) {
220+ [downloadTask removeAllObservers ];
221+
222+ // Upload completed successfully
223+ FIRStorageReference *ref = snapshot.reference ;
224+ NSDictionary *props = @{
225+ @" fullPath" : ref.fullPath ,
226+ @" bucket" : ref.bucket ,
227+ @" name" : ref.name
228+ };
229+
230+ callback (@[[NSNull null ], props]);
231+ }];
232+
233+ [downloadTask observeStatus: FIRStorageTaskStatusFailure handler: ^(FIRStorageTaskSnapshot *snapshot) {
234+ if (snapshot.error != nil ) {
235+ NSDictionary *errProps = [[NSMutableDictionary alloc ] init ];
236+
237+ switch (snapshot.error .code ) {
238+ case FIRStorageErrorCodeObjectNotFound:
239+ // File doesn't exist
240+ [errProps setValue: @" File does not exist" forKey: @" description" ];
241+ break ;
242+ case FIRStorageErrorCodeUnauthorized:
243+ // User doesn't have permission to access file
244+ [errProps setValue: @" You do not have permissions" forKey: @" description" ];
245+ break ;
246+ case FIRStorageErrorCodeCancelled:
247+ // User canceled the upload
248+ [errProps setValue: @" Download canceled" forKey: @" description" ];
249+ break ;
250+ case FIRStorageErrorCodeUnknown:
251+ // Unknown error occurred, inspect the server response
252+ [errProps setValue: @" Unknown error" forKey: @" description" ];
253+ break ;
254+ }
255+
165256 callback (@[errProps]);
166257 }}];
167258}
168259
260+
169261// Not sure how to get away from this... yet
170262- (NSArray <NSString *> *)supportedEvents {
171263 return @[
172264 STORAGE_UPLOAD_PAUSED,
173265 STORAGE_UPLOAD_RESUMED,
174- STORAGE_UPLOAD_PROGRESS
266+ STORAGE_UPLOAD_PROGRESS,
267+ STORAGE_DOWNLOAD_PAUSED,
268+ STORAGE_DOWNLOAD_RESUMED,
269+ STORAGE_DOWNLOAD_PROGRESS
175270 ];
176271}
177272
0 commit comments