@react-native-firebase/storage 20.1.0 → 20.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/android/src/main/java/io/invertase/firebase/storage/ReactNativeFirebaseStorageModule.java +7 -4
- package/ios/RNFBStorage/RNFBStorageModule.m +14 -7
- package/lib/index.js +5 -1
- package/lib/version.js +1 -1
- package/lib/web/RNFBStorageModule.android.js +2 -0
- package/lib/web/RNFBStorageModule.ios.js +2 -0
- package/lib/web/RNFBStorageModule.js +462 -0
- package/package.json +3 -3
    
        package/CHANGELOG.md
    CHANGED
    
    | @@ -3,6 +3,18 @@ | |
| 3 3 | 
             
            All notable changes to this project will be documented in this file.
         | 
| 4 4 | 
             
            See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
         | 
| 5 5 |  | 
| 6 | 
            +
            ## [20.2.1](https://github.com/invertase/react-native-firebase/compare/v20.2.0...v20.2.1) (2024-07-17)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            ### Bug Fixes
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            - **storage:** ensure emulator is used for different storage buckets ([#7892](https://github.com/invertase/react-native-firebase/issues/7892)) ([3fa3f11](https://github.com/invertase/react-native-firebase/commit/3fa3f110b357ef0dbe2cc0fc12e982edc913b588))
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ## [20.2.0](https://github.com/invertase/react-native-firebase/compare/v20.1.0...v20.2.0) (2024-07-15)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ### Features
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            - **other:** Add Storage support ([#7888](https://github.com/invertase/react-native-firebase/issues/7888)) ([9b8dda7](https://github.com/invertase/react-native-firebase/commit/9b8dda704a01243039624bfcc7614021e6c3a527))
         | 
| 17 | 
            +
             | 
| 6 18 | 
             
            ## [20.1.0](https://github.com/invertase/react-native-firebase/compare/v20.0.0...v20.1.0) (2024-06-04)
         | 
| 7 19 |  | 
| 8 20 | 
             
            **Note:** Version bump only for package @react-native-firebase/storage
         | 
    
        package/android/src/main/java/io/invertase/firebase/storage/ReactNativeFirebaseStorageModule.java
    CHANGED
    
    | @@ -281,12 +281,15 @@ public class ReactNativeFirebaseStorageModule extends ReactNativeFirebaseModule | |
| 281 281 | 
             
               * @link https://firebase.google.com/docs/reference/js/firebase.storage.Storage#useEmulator
         | 
| 282 282 | 
             
               */
         | 
| 283 283 | 
             
              @ReactMethod
         | 
| 284 | 
            -
              public void useEmulator(String appName, String host, int port, Promise promise) {
         | 
| 284 | 
            +
              public void useEmulator(String appName, String host, int port, String bucketUrl, Promise promise) {
         | 
| 285 285 | 
             
                FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
         | 
| 286 | 
            -
             | 
| 287 | 
            -
                 | 
| 286 | 
            +
             | 
| 287 | 
            +
                FirebaseStorage firebaseStorage = FirebaseStorage.getInstance(firebaseApp, bucketUrl);
         | 
| 288 | 
            +
                String emulatorKey = appName + ":" + bucketUrl;
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                if (emulatorConfigs.get(emulatorKey) == null) {
         | 
| 288 291 | 
             
                  firebaseStorage.useEmulator(host, port);
         | 
| 289 | 
            -
                  emulatorConfigs.put( | 
| 292 | 
            +
                  emulatorConfigs.put(emulatorKey, "true");
         | 
| 290 293 | 
             
                }
         | 
| 291 294 | 
             
                promise.resolve(null);
         | 
| 292 295 | 
             
              }
         | 
| @@ -511,12 +511,15 @@ RCT_EXPORT_METHOD(putString | |
| 511 511 | 
             
            RCT_EXPORT_METHOD(useEmulator
         | 
| 512 512 | 
             
                              : (FIRApp *)firebaseApp
         | 
| 513 513 | 
             
                              : (nonnull NSString *)host
         | 
| 514 | 
            -
                              : (NSInteger)port | 
| 514 | 
            +
                              : (NSInteger)port
         | 
| 515 | 
            +
                              : (NSString *)bucketUrl) {
         | 
| 515 516 | 
             
              emulatorHost = host;
         | 
| 516 517 | 
             
              emulatorPort = port;
         | 
| 517 | 
            -
               | 
| 518 | 
            -
             | 
| 519 | 
            -
             | 
| 518 | 
            +
              NSString *key = [self createEmulatorKey:bucketUrl appName:firebaseApp.name];
         | 
| 519 | 
            +
             | 
| 520 | 
            +
              if (!emulatorConfigs[key]) {
         | 
| 521 | 
            +
                [[FIRStorage storageForApp:firebaseApp URL:bucketUrl] useEmulatorWithHost:host port:port];
         | 
| 522 | 
            +
                emulatorConfigs[key] = @YES;
         | 
| 520 523 | 
             
              }
         | 
| 521 524 | 
             
            }
         | 
| 522 525 |  | 
| @@ -557,6 +560,10 @@ RCT_EXPORT_METHOD(setTaskStatus | |
| 557 560 | 
             
            #pragma mark -
         | 
| 558 561 | 
             
            #pragma mark Firebase Storage Internals
         | 
| 559 562 |  | 
| 563 | 
            +
            - (NSString *)createEmulatorKey:(NSString *)bucketUrl appName:(NSString *)appName {
         | 
| 564 | 
            +
              return [NSString stringWithFormat:@"%@-%@", appName, bucketUrl];
         | 
| 565 | 
            +
            }
         | 
| 566 | 
            +
             | 
| 560 567 | 
             
            - (void)addUploadTaskObservers:(FIRStorageUploadTask *)uploadTask
         | 
| 561 568 | 
             
                            appDisplayName:(NSString *)appDisplayName
         | 
| 562 569 | 
             
                                    taskId:(NSNumber *)taskId
         | 
| @@ -675,11 +682,11 @@ RCT_EXPORT_METHOD(setTaskStatus | |
| 675 682 | 
             
              storage = [FIRStorage storageForApp:firebaseApp URL:bucket];
         | 
| 676 683 |  | 
| 677 684 | 
             
              NSLog(@"Setting emulator - host %@ port %ld", emulatorHost, (long)emulatorPort);
         | 
| 678 | 
            -
               | 
| 679 | 
            -
             | 
| 685 | 
            +
              NSString *key = [self createEmulatorKey:bucket appName:firebaseApp.name];
         | 
| 686 | 
            +
              if (![emulatorHost isEqual:[NSNull null]] && emulatorHost != nil && !emulatorConfigs[key]) {
         | 
| 680 687 | 
             
                @try {
         | 
| 681 688 | 
             
                  [storage useEmulatorWithHost:emulatorHost port:emulatorPort];
         | 
| 682 | 
            -
                  emulatorConfigs[ | 
| 689 | 
            +
                  emulatorConfigs[key] = @YES;
         | 
| 683 690 | 
             
                } @catch (NSException *e) {
         | 
| 684 691 | 
             
                  NSLog(@"WARNING: Unable to set the Firebase Storage emulator settings. These must be set "
         | 
| 685 692 | 
             
                        @"before any usages of Firebase Storage. If you see this log after a hot "
         | 
    
        package/lib/index.js
    CHANGED
    
    | @@ -16,6 +16,7 @@ | |
| 16 16 | 
             
             */
         | 
| 17 17 |  | 
| 18 18 | 
             
            import { isAndroid, isNumber, isString } from '@react-native-firebase/app/lib/common';
         | 
| 19 | 
            +
            import { setReactNativeModule } from '@react-native-firebase/app/lib/internal/nativeModule';
         | 
| 19 20 | 
             
            import {
         | 
| 20 21 | 
             
              createModuleNamespace,
         | 
| 21 22 | 
             
              FirebaseModule,
         | 
| @@ -25,6 +26,7 @@ import StorageReference from './StorageReference'; | |
| 25 26 | 
             
            import StorageStatics from './StorageStatics';
         | 
| 26 27 | 
             
            import { getGsUrlParts, getHttpUrlParts, handleStorageEvent } from './utils';
         | 
| 27 28 | 
             
            import version from './version';
         | 
| 29 | 
            +
            import fallBackModule from './web/RNFBStorageModule';
         | 
| 28 30 |  | 
| 29 31 | 
             
            export {
         | 
| 30 32 | 
             
              getStorage,
         | 
| @@ -201,7 +203,7 @@ class FirebaseStorageModule extends FirebaseModule { | |
| 201 203 | 
             
                }
         | 
| 202 204 | 
             
                this.emulatorHost = host;
         | 
| 203 205 | 
             
                this.emulatorPort = port;
         | 
| 204 | 
            -
                this.native.useEmulator(_host, port);
         | 
| 206 | 
            +
                this.native.useEmulator(_host, port, this._customUrlOrRegion);
         | 
| 205 207 | 
             
                return [_host, port]; // undocumented return, just used to unit test android host remapping
         | 
| 206 208 | 
             
              }
         | 
| 207 209 | 
             
            }
         | 
| @@ -230,3 +232,5 @@ export default createModuleNamespace({ | |
| 230 232 | 
             
            // storage().X(...);
         | 
| 231 233 | 
             
            // firebase.storage().X(...);
         | 
| 232 234 | 
             
            export const firebase = getFirebaseRoot();
         | 
| 235 | 
            +
             | 
| 236 | 
            +
            setReactNativeModule(nativeModuleName, fallBackModule);
         | 
    
        package/lib/version.js
    CHANGED
    
    | @@ -1,2 +1,2 @@ | |
| 1 1 | 
             
            // Generated by genversion.
         | 
| 2 | 
            -
            module.exports = '20.1 | 
| 2 | 
            +
            module.exports = '20.2.1';
         | 
| @@ -0,0 +1,462 @@ | |
| 1 | 
            +
            import {
         | 
| 2 | 
            +
              getApps,
         | 
| 3 | 
            +
              connectStorageEmulator,
         | 
| 4 | 
            +
              getApp,
         | 
| 5 | 
            +
              getStorage,
         | 
| 6 | 
            +
              deleteObject,
         | 
| 7 | 
            +
              getDownloadURL,
         | 
| 8 | 
            +
              getMetadata,
         | 
| 9 | 
            +
              list,
         | 
| 10 | 
            +
              listAll,
         | 
| 11 | 
            +
              updateMetadata,
         | 
| 12 | 
            +
              uploadBytesResumable,
         | 
| 13 | 
            +
              ref as firebaseStorageRef,
         | 
| 14 | 
            +
            } from '@react-native-firebase/app/lib/internal/web/firebaseStorage';
         | 
| 15 | 
            +
            import { guard, getWebError, emitEvent } from '@react-native-firebase/app/lib/internal/web/utils';
         | 
| 16 | 
            +
            import { Base64 } from '@react-native-firebase/app/lib/common';
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            function rejectWithCodeAndMessage(code, message) {
         | 
| 19 | 
            +
              return Promise.reject(
         | 
| 20 | 
            +
                getWebError({
         | 
| 21 | 
            +
                  code,
         | 
| 22 | 
            +
                  message,
         | 
| 23 | 
            +
                }),
         | 
| 24 | 
            +
              );
         | 
| 25 | 
            +
            }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            function metadataToObject(metadata) {
         | 
| 28 | 
            +
              const out = {
         | 
| 29 | 
            +
                bucket: metadata.bucket,
         | 
| 30 | 
            +
                generation: metadata.generation,
         | 
| 31 | 
            +
                metageneration: metadata.metageneration,
         | 
| 32 | 
            +
                fullPath: metadata.fullPath,
         | 
| 33 | 
            +
                name: metadata.name,
         | 
| 34 | 
            +
                size: metadata.size,
         | 
| 35 | 
            +
                timeCreated: metadata.timeCreated,
         | 
| 36 | 
            +
                updated: metadata.updated,
         | 
| 37 | 
            +
                md5Hash: metadata.md5Hash,
         | 
| 38 | 
            +
              };
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              if ('cacheControl' in metadata) {
         | 
| 41 | 
            +
                out.cacheControl = metadata.cacheControl;
         | 
| 42 | 
            +
              }
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              if ('contentLanguage' in metadata) {
         | 
| 45 | 
            +
                out.contentLanguage = metadata.contentLanguage;
         | 
| 46 | 
            +
              }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              if ('contentDisposition' in metadata) {
         | 
| 49 | 
            +
                out.contentDisposition = metadata.contentDisposition;
         | 
| 50 | 
            +
              }
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              if ('contentEncoding' in metadata) {
         | 
| 53 | 
            +
                out.contentEncoding = metadata.contentEncoding;
         | 
| 54 | 
            +
              }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              if ('contentType' in metadata) {
         | 
| 57 | 
            +
                out.contentType = metadata.contentType;
         | 
| 58 | 
            +
              }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              if ('customMetadata' in metadata) {
         | 
| 61 | 
            +
                out.customMetadata = metadata.customMetadata;
         | 
| 62 | 
            +
                // To match Android/iOS
         | 
| 63 | 
            +
                out.metadata = metadata.customMetadata;
         | 
| 64 | 
            +
              }
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              return out;
         | 
| 67 | 
            +
            }
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            function uploadTaskErrorToObject(error, snapshot) {
         | 
| 70 | 
            +
              return {
         | 
| 71 | 
            +
                ...uploadTaskSnapshotToObject(snapshot),
         | 
| 72 | 
            +
                state: 'error',
         | 
| 73 | 
            +
                error: getWebError(error),
         | 
| 74 | 
            +
              };
         | 
| 75 | 
            +
            }
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            function uploadTaskSnapshotToObject(snapshot) {
         | 
| 78 | 
            +
              return {
         | 
| 79 | 
            +
                totalBytes: snapshot ? snapshot.totalBytes : 0,
         | 
| 80 | 
            +
                bytesTransferred: snapshot ? snapshot.bytesTransferred : 0,
         | 
| 81 | 
            +
                state: snapshot ? taskStateToString(snapshot.state) : 'unknown',
         | 
| 82 | 
            +
                metadata: snapshot ? metadataToObject(snapshot.metadata) : {},
         | 
| 83 | 
            +
              };
         | 
| 84 | 
            +
            }
         | 
| 85 | 
            +
             | 
| 86 | 
            +
            function taskStateToString(state) {
         | 
| 87 | 
            +
              const override = {
         | 
| 88 | 
            +
                canceled: 'cancelled',
         | 
| 89 | 
            +
              };
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              if (state in override) {
         | 
| 92 | 
            +
                return override[state];
         | 
| 93 | 
            +
              }
         | 
| 94 | 
            +
             | 
| 95 | 
            +
              return state;
         | 
| 96 | 
            +
            }
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            function makeSettableMetadata(metadata) {
         | 
| 99 | 
            +
              return {
         | 
| 100 | 
            +
                cacheControl: metadata.cacheControl,
         | 
| 101 | 
            +
                contentDisposition: metadata.contentDisposition,
         | 
| 102 | 
            +
                contentEncoding: metadata.contentEncoding,
         | 
| 103 | 
            +
                contentType: metadata.contentType,
         | 
| 104 | 
            +
                contentLanguage: metadata.contentLanguage,
         | 
| 105 | 
            +
                customMetadata: metadata.customMetadata,
         | 
| 106 | 
            +
              };
         | 
| 107 | 
            +
            }
         | 
| 108 | 
            +
             | 
| 109 | 
            +
            function listResultToObject(result) {
         | 
| 110 | 
            +
              return {
         | 
| 111 | 
            +
                nextPageToken: result.nextPageToken,
         | 
| 112 | 
            +
                items: result.items.map(ref => ref.fullPath),
         | 
| 113 | 
            +
                prefixes: result.prefixes.map(ref => ref.fullPath),
         | 
| 114 | 
            +
              };
         | 
| 115 | 
            +
            }
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            const emulatorForApp = {};
         | 
| 118 | 
            +
            const appInstances = {};
         | 
| 119 | 
            +
            const storageInstances = {};
         | 
| 120 | 
            +
            const tasks = {};
         | 
| 121 | 
            +
             | 
| 122 | 
            +
            function getBucketFromUrl(url) {
         | 
| 123 | 
            +
              const pathWithBucketName = url.substring(5);
         | 
| 124 | 
            +
              const bucket = url.substring(0, pathWithBucketName.indexOf('/') + 5);
         | 
| 125 | 
            +
              return bucket;
         | 
| 126 | 
            +
            }
         | 
| 127 | 
            +
             | 
| 128 | 
            +
            function getCachedAppInstance(appName) {
         | 
| 129 | 
            +
              return (appInstances[appName] ??= getApp(appName));
         | 
| 130 | 
            +
            }
         | 
| 131 | 
            +
             | 
| 132 | 
            +
            // Returns a cached Storage instance.
         | 
| 133 | 
            +
            function getCachedStorageInstance(appName, url) {
         | 
| 134 | 
            +
              let instance;
         | 
| 135 | 
            +
              if (!url) {
         | 
| 136 | 
            +
                instance = getCachedStorageInstance(
         | 
| 137 | 
            +
                  appName,
         | 
| 138 | 
            +
                  getCachedAppInstance(appName).options.storageBucket,
         | 
| 139 | 
            +
                );
         | 
| 140 | 
            +
              } else {
         | 
| 141 | 
            +
                const bucket = getBucketFromUrl(url);
         | 
| 142 | 
            +
                instance = storageInstances[`${appName}|${bucket}`] ??= getStorage(
         | 
| 143 | 
            +
                  getCachedAppInstance(appName),
         | 
| 144 | 
            +
                  bucket,
         | 
| 145 | 
            +
                );
         | 
| 146 | 
            +
              }
         | 
| 147 | 
            +
              if (emulatorForApp[appName]) {
         | 
| 148 | 
            +
                connectStorageEmulator(instance, emulatorForApp[appName].host, emulatorForApp[appName].port);
         | 
| 149 | 
            +
              }
         | 
| 150 | 
            +
              return instance;
         | 
| 151 | 
            +
            }
         | 
| 152 | 
            +
             | 
| 153 | 
            +
            // Returns a Storage Reference.
         | 
| 154 | 
            +
            function getReferenceFromUrl(appName, url) {
         | 
| 155 | 
            +
              const path = url.substring(url.indexOf('/') + 1);
         | 
| 156 | 
            +
              const instance = getCachedStorageInstance(appName, path);
         | 
| 157 | 
            +
              return firebaseStorageRef(instance, url);
         | 
| 158 | 
            +
            }
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            const CONSTANTS = {};
         | 
| 161 | 
            +
            const defaultAppInstance = getApps()[0];
         | 
| 162 | 
            +
             | 
| 163 | 
            +
            if (defaultAppInstance) {
         | 
| 164 | 
            +
              CONSTANTS.maxDownloadRetryTime = 0;
         | 
| 165 | 
            +
              CONSTANTS.maxOperationRetryTime = 0;
         | 
| 166 | 
            +
              CONSTANTS.maxUploadRetryTime = 0;
         | 
| 167 | 
            +
            }
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            export default {
         | 
| 170 | 
            +
              ...CONSTANTS,
         | 
| 171 | 
            +
             | 
| 172 | 
            +
              /**
         | 
| 173 | 
            +
               * Delete an object at the path.
         | 
| 174 | 
            +
               * @param {string} appName - The app name.
         | 
| 175 | 
            +
               * @param {string} url - The path to the object.
         | 
| 176 | 
            +
               * @return {Promise<void>}
         | 
| 177 | 
            +
               */
         | 
| 178 | 
            +
              delete(appName, url) {
         | 
| 179 | 
            +
                return guard(async () => {
         | 
| 180 | 
            +
                  const ref = getReferenceFromUrl(appName, url);
         | 
| 181 | 
            +
                  await deleteObject(ref);
         | 
| 182 | 
            +
                });
         | 
| 183 | 
            +
              },
         | 
| 184 | 
            +
             | 
| 185 | 
            +
              /**
         | 
| 186 | 
            +
               * Get the download URL for an object.
         | 
| 187 | 
            +
               * @param {string} appName - The app name.
         | 
| 188 | 
            +
               * @param {string} url - The path to the object.
         | 
| 189 | 
            +
               * @return {Promise<string>} The download URL.
         | 
| 190 | 
            +
               */
         | 
| 191 | 
            +
              getDownloadURL(appName, url) {
         | 
| 192 | 
            +
                return guard(async () => {
         | 
| 193 | 
            +
                  const ref = getReferenceFromUrl(appName, url);
         | 
| 194 | 
            +
                  const downloadURL = await getDownloadURL(ref);
         | 
| 195 | 
            +
                  return downloadURL;
         | 
| 196 | 
            +
                });
         | 
| 197 | 
            +
              },
         | 
| 198 | 
            +
             | 
| 199 | 
            +
              /**
         | 
| 200 | 
            +
               * Get the metadata for an object.
         | 
| 201 | 
            +
               * @param {string} appName - The app name.
         | 
| 202 | 
            +
               * @param {string} url - The path to the object.
         | 
| 203 | 
            +
               * @return {Promise<Object>} The metadata.
         | 
| 204 | 
            +
               */
         | 
| 205 | 
            +
              getMetadata(appName, url) {
         | 
| 206 | 
            +
                return guard(async () => {
         | 
| 207 | 
            +
                  const ref = getReferenceFromUrl(appName, url);
         | 
| 208 | 
            +
                  const metadata = await getMetadata(ref);
         | 
| 209 | 
            +
                  return metadataToObject(metadata);
         | 
| 210 | 
            +
                });
         | 
| 211 | 
            +
              },
         | 
| 212 | 
            +
             | 
| 213 | 
            +
              /**
         | 
| 214 | 
            +
               * List objects at the path.
         | 
| 215 | 
            +
               * @param {string} appName - The app name.
         | 
| 216 | 
            +
               * @param {string} url - The path to the object.
         | 
| 217 | 
            +
               * @param {Object} listOptions - The list options.
         | 
| 218 | 
            +
               * @return {Promise<Object>} The list result.
         | 
| 219 | 
            +
               */
         | 
| 220 | 
            +
              list(appName, url, listOptions) {
         | 
| 221 | 
            +
                return guard(async () => {
         | 
| 222 | 
            +
                  const ref = getReferenceFromUrl(appName, url);
         | 
| 223 | 
            +
                  const listResult = await list(ref, listOptions);
         | 
| 224 | 
            +
                  return listResultToObject(listResult);
         | 
| 225 | 
            +
                });
         | 
| 226 | 
            +
              },
         | 
| 227 | 
            +
             | 
| 228 | 
            +
              /**
         | 
| 229 | 
            +
               * List all objects at the path.
         | 
| 230 | 
            +
               * @param {string} appName - The app name.
         | 
| 231 | 
            +
               * @param {string} url - The path to the object.
         | 
| 232 | 
            +
               * @return {Promise<Object>} The list result.
         | 
| 233 | 
            +
               */
         | 
| 234 | 
            +
              listAll(appName, url) {
         | 
| 235 | 
            +
                return guard(async () => {
         | 
| 236 | 
            +
                  const ref = getReferenceFromUrl(appName, url);
         | 
| 237 | 
            +
                  const listResult = await listAll(ref);
         | 
| 238 | 
            +
                  return listResultToObject(listResult);
         | 
| 239 | 
            +
                });
         | 
| 240 | 
            +
              },
         | 
| 241 | 
            +
             | 
| 242 | 
            +
              /**
         | 
| 243 | 
            +
               * Update the metadata for an object.
         | 
| 244 | 
            +
               * @param {string} appName - The app name.
         | 
| 245 | 
            +
               * @param {string} url - The path to the object.
         | 
| 246 | 
            +
               * @param {Object} metadata - The metadata (SettableMetadata).
         | 
| 247 | 
            +
               */
         | 
| 248 | 
            +
              updateMetadata(appName, url, metadata) {
         | 
| 249 | 
            +
                return guard(async () => {
         | 
| 250 | 
            +
                  const ref = getReferenceFromUrl(appName, url);
         | 
| 251 | 
            +
                  const updated = await updateMetadata(ref, makeSettableMetadata(metadata));
         | 
| 252 | 
            +
                  return metadataToObject(updated);
         | 
| 253 | 
            +
                });
         | 
| 254 | 
            +
              },
         | 
| 255 | 
            +
             | 
| 256 | 
            +
              setMaxDownloadRetryTime() {
         | 
| 257 | 
            +
                if (__DEV__) {
         | 
| 258 | 
            +
                  // eslint-disable-next-line no-console
         | 
| 259 | 
            +
                  console.warn(
         | 
| 260 | 
            +
                    'The Firebase Storage `setMaxDownloadRetryTime` method is not available in the this environment.',
         | 
| 261 | 
            +
                  );
         | 
| 262 | 
            +
                  return;
         | 
| 263 | 
            +
                }
         | 
| 264 | 
            +
              },
         | 
| 265 | 
            +
             | 
| 266 | 
            +
              /**
         | 
| 267 | 
            +
               * Set the maximum operation retry time.
         | 
| 268 | 
            +
               * @param {string} appName - The app name.
         | 
| 269 | 
            +
               * @param {number} milliseconds - The maximum operation retry time.
         | 
| 270 | 
            +
               * @return {Promise<void>}
         | 
| 271 | 
            +
               */
         | 
| 272 | 
            +
              setMaxOperationRetryTime(appName, milliseconds) {
         | 
| 273 | 
            +
                return guard(async () => {
         | 
| 274 | 
            +
                  const storage = getCachedStorageInstance(appName);
         | 
| 275 | 
            +
                  storage.maxOperationRetryTime = milliseconds;
         | 
| 276 | 
            +
                });
         | 
| 277 | 
            +
              },
         | 
| 278 | 
            +
             | 
| 279 | 
            +
              /**
         | 
| 280 | 
            +
               * Set the maximum upload retry time.
         | 
| 281 | 
            +
               * @param {string} appName - The app name.
         | 
| 282 | 
            +
               * @param {number} milliseconds - The maximum upload retry time.
         | 
| 283 | 
            +
               * @return {Promise<void>}
         | 
| 284 | 
            +
               */
         | 
| 285 | 
            +
              setMaxUploadRetryTime(appName, milliseconds) {
         | 
| 286 | 
            +
                return guard(async () => {
         | 
| 287 | 
            +
                  const storage = getCachedStorageInstance(appName);
         | 
| 288 | 
            +
                  storage.maxUploadRetryTime = milliseconds;
         | 
| 289 | 
            +
                });
         | 
| 290 | 
            +
              },
         | 
| 291 | 
            +
             | 
| 292 | 
            +
              /**
         | 
| 293 | 
            +
               * Use the Firebase Storage emulator.
         | 
| 294 | 
            +
               * @param {string} appName - The app name.
         | 
| 295 | 
            +
               * @param {string} host - The emulator host.
         | 
| 296 | 
            +
               * @param {number} port - The emulator port.
         | 
| 297 | 
            +
               * @return {Promise<void>}
         | 
| 298 | 
            +
               */
         | 
| 299 | 
            +
              useEmulator(appName, host, port) {
         | 
| 300 | 
            +
                return guard(async () => {
         | 
| 301 | 
            +
                  const instance = getCachedStorageInstance(appName);
         | 
| 302 | 
            +
                  connectStorageEmulator(instance, host, port);
         | 
| 303 | 
            +
                  emulatorForApp[appName] = { host, port };
         | 
| 304 | 
            +
                });
         | 
| 305 | 
            +
              },
         | 
| 306 | 
            +
             | 
| 307 | 
            +
              writeToFile() {
         | 
| 308 | 
            +
                return rejectWithCodeAndMessage(
         | 
| 309 | 
            +
                  'unsupported',
         | 
| 310 | 
            +
                  'This operation is not supported in this environment.',
         | 
| 311 | 
            +
                );
         | 
| 312 | 
            +
              },
         | 
| 313 | 
            +
             | 
| 314 | 
            +
              /**
         | 
| 315 | 
            +
               * Put a string to the path.
         | 
| 316 | 
            +
               * @param {string} appName - The app name.
         | 
| 317 | 
            +
               * @param {string} url - The path to the object.
         | 
| 318 | 
            +
               * @param {string} string - The string to put.
         | 
| 319 | 
            +
               * @param {string} format - The format of the string.
         | 
| 320 | 
            +
               * @param {Object} metadata - The metadata (SettableMetadata).
         | 
| 321 | 
            +
               * @param {string} taskId - The task ID.
         | 
| 322 | 
            +
               * @return {Promise<Object>} The upload snapshot.
         | 
| 323 | 
            +
               */
         | 
| 324 | 
            +
              putString(appName, url, string, format, metadata = {}, taskId) {
         | 
| 325 | 
            +
                return guard(async () => {
         | 
| 326 | 
            +
                  const ref = getReferenceFromUrl(appName, url);
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                  let base64String = null;
         | 
| 329 | 
            +
             | 
| 330 | 
            +
                  switch (format) {
         | 
| 331 | 
            +
                    case 'base64':
         | 
| 332 | 
            +
                      base64String = Base64.atob(string);
         | 
| 333 | 
            +
                      break;
         | 
| 334 | 
            +
                    case 'base64url':
         | 
| 335 | 
            +
                      base64String = Base64.atob(string.replace(/_/g, '/').replace(/-/g, '+'));
         | 
| 336 | 
            +
                      break;
         | 
| 337 | 
            +
                  }
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                  const byteArray = new Uint8Array(base64String ? base64String.length : 0);
         | 
| 340 | 
            +
             | 
| 341 | 
            +
                  if (base64String) {
         | 
| 342 | 
            +
                    for (let i = 0; i < base64String.length; i++) {
         | 
| 343 | 
            +
                      byteArray[i] = base64String.charCodeAt(i);
         | 
| 344 | 
            +
                    }
         | 
| 345 | 
            +
                  }
         | 
| 346 | 
            +
             | 
| 347 | 
            +
                  // Start a resumable upload task.
         | 
| 348 | 
            +
                  const task = uploadBytesResumable(ref, byteArray, {
         | 
| 349 | 
            +
                    ...makeSettableMetadata(metadata),
         | 
| 350 | 
            +
                    md5Hash: metadata.md5Hash,
         | 
| 351 | 
            +
                  });
         | 
| 352 | 
            +
             | 
| 353 | 
            +
                  // Store the task in the tasks map.
         | 
| 354 | 
            +
                  tasks[taskId] = task;
         | 
| 355 | 
            +
             | 
| 356 | 
            +
                  const snapshot = await new Promise((resolve, reject) => {
         | 
| 357 | 
            +
                    task.on(
         | 
| 358 | 
            +
                      'state_changed',
         | 
| 359 | 
            +
                      snapshot => {
         | 
| 360 | 
            +
                        const event = {
         | 
| 361 | 
            +
                          body: uploadTaskSnapshotToObject(snapshot),
         | 
| 362 | 
            +
                          appName,
         | 
| 363 | 
            +
                          taskId,
         | 
| 364 | 
            +
                          eventName: 'state_changed',
         | 
| 365 | 
            +
                        };
         | 
| 366 | 
            +
                        emitEvent('storage_event', event);
         | 
| 367 | 
            +
                      },
         | 
| 368 | 
            +
                      error => {
         | 
| 369 | 
            +
                        const errorSnapshot = uploadTaskErrorToObject(error, task.snapshot);
         | 
| 370 | 
            +
                        const event = {
         | 
| 371 | 
            +
                          body: {
         | 
| 372 | 
            +
                            ...errorSnapshot,
         | 
| 373 | 
            +
                            state: 'error',
         | 
| 374 | 
            +
                          },
         | 
| 375 | 
            +
                          appName,
         | 
| 376 | 
            +
                          taskId,
         | 
| 377 | 
            +
                          eventName: 'state_changed',
         | 
| 378 | 
            +
                        };
         | 
| 379 | 
            +
                        emitEvent('storage_event', event);
         | 
| 380 | 
            +
                        emitEvent('storage_event', {
         | 
| 381 | 
            +
                          ...event,
         | 
| 382 | 
            +
                          eventName: 'upload_failure',
         | 
| 383 | 
            +
                        });
         | 
| 384 | 
            +
                        delete tasks[taskId];
         | 
| 385 | 
            +
                        reject(error);
         | 
| 386 | 
            +
                      },
         | 
| 387 | 
            +
                      () => {
         | 
| 388 | 
            +
                        delete tasks[taskId];
         | 
| 389 | 
            +
                        const event = {
         | 
| 390 | 
            +
                          body: {
         | 
| 391 | 
            +
                            ...uploadTaskSnapshotToObject(snapshot),
         | 
| 392 | 
            +
                            state: 'success',
         | 
| 393 | 
            +
                          },
         | 
| 394 | 
            +
                          appName,
         | 
| 395 | 
            +
                          taskId,
         | 
| 396 | 
            +
                          eventName: 'state_changed',
         | 
| 397 | 
            +
                        };
         | 
| 398 | 
            +
                        emitEvent('storage_event', event);
         | 
| 399 | 
            +
                        emitEvent('storage_event', {
         | 
| 400 | 
            +
                          ...event,
         | 
| 401 | 
            +
                          eventName: 'upload_success',
         | 
| 402 | 
            +
                        });
         | 
| 403 | 
            +
                        resolve(task.snapshot);
         | 
| 404 | 
            +
                      },
         | 
| 405 | 
            +
                    );
         | 
| 406 | 
            +
                  });
         | 
| 407 | 
            +
             | 
| 408 | 
            +
                  return uploadTaskSnapshotToObject(snapshot);
         | 
| 409 | 
            +
                });
         | 
| 410 | 
            +
              },
         | 
| 411 | 
            +
             | 
| 412 | 
            +
              putFile() {
         | 
| 413 | 
            +
                return rejectWithCodeAndMessage(
         | 
| 414 | 
            +
                  'unsupported',
         | 
| 415 | 
            +
                  'This operation is not supported in this environment.',
         | 
| 416 | 
            +
                );
         | 
| 417 | 
            +
              },
         | 
| 418 | 
            +
             | 
| 419 | 
            +
              /**
         | 
| 420 | 
            +
               * Set the status of a task.
         | 
| 421 | 
            +
               * @param {string} appName - The app name.
         | 
| 422 | 
            +
               * @param {string} taskId - The task ID.
         | 
| 423 | 
            +
               * @param {number} status - The status.
         | 
| 424 | 
            +
               * @return {Promise<boolean>} Whether the status was set.
         | 
| 425 | 
            +
               */
         | 
| 426 | 
            +
              setTaskStatus(appName, taskId, status) {
         | 
| 427 | 
            +
                // TODO this function implementation cannot
         | 
| 428 | 
            +
                // be tested right now since we're unable
         | 
| 429 | 
            +
                // to create a big enough upload to be able to
         | 
| 430 | 
            +
                // pause/resume/cancel it in time.
         | 
| 431 | 
            +
                return guard(async () => {
         | 
| 432 | 
            +
                  const task = tasks[taskId];
         | 
| 433 | 
            +
             | 
| 434 | 
            +
                  // If the task doesn't exist, return false.
         | 
| 435 | 
            +
                  if (!task) {
         | 
| 436 | 
            +
                    return false;
         | 
| 437 | 
            +
                  }
         | 
| 438 | 
            +
             | 
| 439 | 
            +
                  let result = false;
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                  switch (status) {
         | 
| 442 | 
            +
                    case 0:
         | 
| 443 | 
            +
                      result = await task.pause();
         | 
| 444 | 
            +
                      break;
         | 
| 445 | 
            +
                    case 1:
         | 
| 446 | 
            +
                      result = await task.resume();
         | 
| 447 | 
            +
                      break;
         | 
| 448 | 
            +
                    case 2:
         | 
| 449 | 
            +
                      result = await task.cancel();
         | 
| 450 | 
            +
                      break;
         | 
| 451 | 
            +
                  }
         | 
| 452 | 
            +
             | 
| 453 | 
            +
                  emitEvent('storage_event', {
         | 
| 454 | 
            +
                    data: buildUploadSnapshotMap(task.snapshot),
         | 
| 455 | 
            +
                    appName,
         | 
| 456 | 
            +
                    taskId,
         | 
| 457 | 
            +
                  });
         | 
| 458 | 
            +
             | 
| 459 | 
            +
                  return result;
         | 
| 460 | 
            +
                });
         | 
| 461 | 
            +
              },
         | 
| 462 | 
            +
            };
         | 
    
        package/package.json
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            {
         | 
| 2 2 | 
             
              "name": "@react-native-firebase/storage",
         | 
| 3 | 
            -
              "version": "20.1 | 
| 3 | 
            +
              "version": "20.2.1",
         | 
| 4 4 | 
             
              "author": "Invertase <oss@invertase.io> (http://invertase.io)",
         | 
| 5 5 | 
             
              "description": "React Native Firebase - React Native Firebase provides native integration with Cloud Storage, providing support to upload and download files directly from your device and from your Firebase Cloud Storage bucket.",
         | 
| 6 6 | 
             
              "main": "lib/index.js",
         | 
| @@ -29,10 +29,10 @@ | |
| 29 29 | 
             
                "download"
         | 
| 30 30 | 
             
              ],
         | 
| 31 31 | 
             
              "peerDependencies": {
         | 
| 32 | 
            -
                "@react-native-firebase/app": "20.1 | 
| 32 | 
            +
                "@react-native-firebase/app": "20.2.1"
         | 
| 33 33 | 
             
              },
         | 
| 34 34 | 
             
              "publishConfig": {
         | 
| 35 35 | 
             
                "access": "public"
         | 
| 36 36 | 
             
              },
         | 
| 37 | 
            -
              "gitHead": " | 
| 37 | 
            +
              "gitHead": "2c787c2dbefbefcc637018e1e5d74a73b39600ab"
         | 
| 38 38 | 
             
            }
         |