UNPKG

@react-native-firebase/storage

Version:

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.

407 lines (374 loc) 14.7 kB
"use strict"; /* * Copyright (c) 2016-present Invertase Limited & Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this library except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { isAndroid, isNumber, isString } from '@react-native-firebase/app/dist/module/common'; import { FirebaseModule, getOrCreateModularInstance } from '@react-native-firebase/app/dist/module/internal'; import Reference from "./StorageReference.js"; import { getGsUrlParts, getHttpUrlParts, handleStorageEvent } from "./utils.js"; import { version } from "./version.js"; import fallBackModule from './web/RNFBStorageModule'; import { setReactNativeModule } from '@react-native-firebase/app/dist/module/internal/nativeModule'; import "./types/internal.js"; const nativeEvents = ['storage_event']; const nativeModuleName = 'NativeRNFBTurboStorage'; const config = { namespace: 'storage', nativeEvents, nativeModuleName, hasMultiAppSupport: true, hasCustomUrlOrRegionSupport: true, disablePrependCustomUrlOrRegion: true, turboModule: true }; class FirebaseStorageModule extends FirebaseModule { constructor(app, config, bucketUrl) { super(app, config, bucketUrl ?? undefined); if (bucketUrl == null) { this._customUrlOrRegion = `gs://${app.options.storageBucket}`; } else if (!isString(bucketUrl) || !bucketUrl.startsWith('gs://')) { throw new Error("firebase.app().storage(*) bucket url must be a string and begin with 'gs://'"); } const storageEvent = nativeEvents[0]; if (!storageEvent) { throw new Error('storage_event is not defined in nativeEvents'); } this.emitter.addListener(this.eventNameForApp(storageEvent), handleStorageEvent.bind(null, this)); // Emulator instance vars needed to send through on iOS, iOS does not persist emulator state between calls this.emulatorHost = undefined; this.emulatorPort = 0; this._maxUploadRetryTime = this.native.maxUploadRetryTime || 0; this._maxDownloadRetryTime = this.native.maxDownloadRetryTime || 0; this._maxOperationRetryTime = this.native.maxOperationRetryTime || 0; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setmaxuploadretrytime */ get maxUploadRetryTime() { return this._maxUploadRetryTime; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setmaxdownloadretrytime */ get maxDownloadRetryTime() { return this._maxDownloadRetryTime; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#maxoperationretrytime */ get maxOperationRetryTime() { return this._maxOperationRetryTime; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#ref */ ref(path = '/') { if (!isString(path)) { throw new Error("firebase.storage().ref(*) 'path' must be a string value."); } return new Reference(this, path); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#refFromURL */ refFromURL(url) { if (!isString(url) || !url.startsWith('gs://') && !url.startsWith('http')) { throw new Error("firebase.storage().refFromURL(*) 'url' must be a string value and begin with 'gs://' or 'https://'."); } let path; let bucket; if (url.startsWith('http')) { const parts = getHttpUrlParts(url); if (!parts) { throw new Error("firebase.storage().refFromURL(*) unable to parse 'url', ensure it's a valid storage url'."); } ({ bucket, path } = parts); } else { ({ bucket, path } = getGsUrlParts(url)); } const storageInstance = getOrCreateModularInstance(FirebaseStorageModule, config, this.app, bucket); return new Reference(storageInstance, path); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxOperationRetryTime */ setMaxOperationRetryTime(time) { if (!isNumber(time)) { throw new Error("firebase.storage().setMaxOperationRetryTime(*) 'time' must be a number value."); } this._maxOperationRetryTime = time; return this.native.setMaxOperationRetryTime(time); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxUploadRetryTime */ setMaxUploadRetryTime(time) { if (!isNumber(time)) { throw new Error("firebase.storage().setMaxUploadRetryTime(*) 'time' must be a number value."); } this._maxUploadRetryTime = time; return this.native.setMaxUploadRetryTime(time); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxDownloadRetryTime */ setMaxDownloadRetryTime(time) { if (!isNumber(time)) { throw new Error("firebase.storage().setMaxDownloadRetryTime(*) 'time' must be a number value."); } this._maxDownloadRetryTime = time; return this.native.setMaxDownloadRetryTime(time); } useEmulator(host, port, _options) { if (!host || !isString(host) || !port || !isNumber(port)) { throw new Error('firebase.storage().useEmulator() takes a non-empty host and port'); } let _host = host; const androidBypassEmulatorUrlRemap = typeof this.firebaseJson.android_bypass_emulator_url_remap === 'boolean' && this.firebaseJson.android_bypass_emulator_url_remap; if (!androidBypassEmulatorUrlRemap && isAndroid && _host) { if (_host === 'localhost' || _host === '127.0.0.1') { _host = '10.0.2.2'; // eslint-disable-next-line no-console console.log('Mapping storage host to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.'); } } this.emulatorHost = host; this.emulatorPort = port; this.native.useEmulator(_host, port, this._customUrlOrRegion); // @ts-ignore undocumented return, just used to unit test android host remapping return [_host, port]; } } export const SDK_VERSION = version; export function getStorage(app, bucketUrl) { return getOrCreateModularInstance(FirebaseStorageModule, config, app, bucketUrl); } export { StringFormat, TaskEvent, TaskState } from "./StorageStatics.js"; function isUrl(path) { if (typeof path !== 'string') { return false; } return /^[A-Za-z]+:\/\//.test(decodeURIComponent(path)); } /** * Modify this Storage instance to communicate with the Firebase Storage emulator. * @param storage - Storage instance. * @param host - emulator host (e.g. - 'localhost') * @param port - emulator port (e.g. - 9199) * @param options - `EmulatorMockTokenOptions` instance. Optional. Web only. * @returns {void} */ export function connectStorageEmulator(storage, host, port, options) { return storage.useEmulator(host, port, options); } /** * Returns a StorageReference for the given URL or path in the default bucket. * @param storage - FirebaseStorage instance. * @param url - Optional gs:// or https:// URL, or path. If empty, returns root reference. * @returns {StorageReference} */ /** * Returns a StorageReference for the given path, or the same reference if path is omitted. * @param storageRef - StorageReference instance. * @param path - Optional child path. If omitted, returns the same reference. * @returns {StorageReference} */ export function ref(storageOrRef, path) { // ref(parentRef, path) → child reference; ref(parentRef) → same reference (firebase-js-sdk overload) if (typeof storageOrRef.fullPath === 'string') { if (path === undefined) { return storageOrRef; } return storageOrRef.child(path); } const storage = storageOrRef; if (path != null && isUrl(path)) { return storage.refFromURL(path); } return storage.ref(path); } /** * Deletes the object at this reference's location. * @param storageRef - Storage `Reference` instance. * @returns {Promise<void>} */ export function deleteObject(storageRef) { return storageRef.delete(); } /** * Downloads the data at the object's location. Returns an error if the object is not found. * @param _storageRef - Storage `Reference` instance. * @param _maxDownloadSizeBytes - The maximum allowed size in bytes to retrieve. Web only. * @returns {Promise<Blob>} */ export function getBlob(_storageRef, _maxDownloadSizeBytes) { throw new Error('`getBlob()` is not implemented'); } /** * Downloads the data at the object's location. Returns an error if the object is not found. * @param _storageRef - Storage `Reference` instance. * @param _maxDownloadSizeBytes - The maximum allowed size in bytes to retrieve. Web only. * @returns {Promise<ArrayBuffer>} */ export function getBytes(_storageRef, _maxDownloadSizeBytes) { throw new Error('`getBytes()` is not implemented'); } /** * Deletes the object at this reference's location. * @param storageRef - Storage `Reference` instance. * @returns {Promise<string>} */ export function getDownloadURL(storageRef) { return storageRef.getDownloadURL(); } /** * Fetches metadata for the object at this location, if one exists. * @param storageRef - Storage `Reference` instance. * @returns {Promise<FullMetadata>} */ export function getMetadata(storageRef) { return storageRef.getMetadata(); } /** * Downloads the data at the object's location. This API is only available in Nodejs. * @param _storageRef - Storage `Reference` instance. * @param _maxDownloadSizeBytes - The maximum allowed size in bytes to retrieve. Web only. * @returns {NodeJS.ReadableStream;} */ export function getStream(_storageRef, _maxDownloadSizeBytes) { throw new Error('`getStream()` is not implemented'); } /** * List items (files) and prefixes (folders) under this storage reference * @param storageRef - Storage `Reference` instance. * @param options - Storage `ListOptions` instance. The options list() accepts. * @returns {Promise<ListResult>} */ export async function list(storageRef, options) { const result = await storageRef.list(options); if (result.nextPageToken === null) { delete result.nextPageToken; } return result; } /** * List all items (files) and prefixes (folders) under this storage reference. * @param storageRef - Storage `Reference` instance. * @returns {Promise<ListResult>} */ export async function listAll(storageRef) { const result = await storageRef.listAll(); if (result.nextPageToken === null) { delete result.nextPageToken; } return result; } /** * Updates the metadata for this object. * @param storageRef - Storage `Reference` instance. * @param metadata - A Storage `SettableMetadata` instance to update. * @returns {Promise<FullMetadata>} */ export function updateMetadata(storageRef, metadata) { return storageRef.updateMetadata(metadata); } /** * Uploads data to this object's location. The upload is not resumable. * @param _storageRef - Storage `Reference` instance. * @param _data - The data (Blob | Uint8Array | ArrayBuffer) to upload to the storage bucket at the reference location. * @param _metadata - A Storage `UploadMetadata` instance to update. Optional. * @returns {Promise<UploadResult>} */ export async function uploadBytes(_storageRef, _data, _metadata) { throw new Error('`uploadBytes()` is not implemented'); } /** * Uploads data to this object's location. The upload is not resumable. * @param storageRef - Storage `Reference` instance. * @param data - The data (Blob | Uint8Array | ArrayBuffer) to upload to the storage bucket at the reference location. * @param metadata - A Storage `UploadMetadata` instance to update. Optional. * @returns {UploadTask} */ export function uploadBytesResumable(storageRef, data, metadata) { return storageRef.put(data, metadata); } /** * Uploads data to this object's location. The upload is not resumable. * @param storageRef - Storage `Reference` instance. * @param data - The string to upload. * @param format - The format of the string to upload ('raw' | 'base64' | 'base64url' | 'data_url'). Optional. * @param metadata - A Storage `UploadMetadata` instance to update. Optional. * @returns {Task} */ export function uploadString(storageRef, data, format, metadata) { return storageRef.putString(data, format, metadata); } // Methods not on the Firebase JS SDK below /** * Sets the maximum time in milliseconds to retry non-upload/download operations. * * @remarks React Native Firebase-specific modular helper. The firebase-js-sdk exposes this as a * writable property on the `FirebaseStorage` instance. **Android and iOS only.** */ export function setMaxOperationRetryTime(storage, time) { return storage.setMaxOperationRetryTime(time); } /** * Sets the maximum time in milliseconds to retry an upload if a failure occurs. * * @remarks React Native Firebase-specific modular helper. The firebase-js-sdk exposes this as a * writable property on the `FirebaseStorage` instance. **Android and iOS only.** */ export function setMaxUploadRetryTime(storage, time) { return storage.setMaxUploadRetryTime(time); } /** * Uploads a file from a local device path to Cloud Storage. * * @remarks React Native Firebase-specific API with **no firebase-js-sdk equivalent**. Use * `FilePath` from `@react-native-firebase/app` for portable device paths. **Native only** * — throws on Web interop. */ export function putFile(storageRef, filePath, metadata) { return storageRef.putFile(filePath, metadata); } /** * Downloads a Cloud Storage object to a local device file path. * * @remarks React Native Firebase-specific API with **no firebase-js-sdk equivalent**. Use * `FilePath` from `@react-native-firebase/app` for portable device paths. **Native only** * — throws on Web interop. */ export function writeToFile(storageRef, filePath) { return storageRef.writeToFile(filePath); } /** * Sets the maximum time in milliseconds to retry a download if a failure occurs. * * @remarks React Native Firebase-specific modular helper with no direct firebase-js-sdk equivalent. * **Android and iOS only.** */ export function setMaxDownloadRetryTime(storage, time) { return storage.setMaxDownloadRetryTime(time); } setReactNativeModule(nativeModuleName, fallBackModule); //# sourceMappingURL=index.js.map