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.

351 lines (308 loc) 10.6 kB
/* * 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 { Base64, getDataUrlParts, hasOwnProperty, isInteger, isNumber, isObject, isString, isUndefined, pathChild, pathLastComponent, pathParent, ReferenceBase, toFilePath, } from '@react-native-firebase/app/dist/module/common'; import StorageDownloadTask from './StorageDownloadTask'; import StorageListResult, { provideStorageReferenceClass } from './StorageListResult'; import { StringFormat } from './StorageStatics'; import StorageUploadTask from './StorageUploadTask'; import { validateMetadata } from './utils'; import type { StorageReference, SettableMetadata, UploadMetadata, ListOptions, FullMetadata, Task, FirebaseStorage, } from './types/storage'; import type { ListResultInternal, StorageInternal } from './types/internal'; export default class Reference extends ReferenceBase implements StorageReference { _storage: StorageInternal; constructor(storage: StorageInternal, path: string) { super(path); this._storage = storage; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#bucket */ get bucket(): string { return this._storage._customUrlOrRegion!.replace('gs://', ''); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#fullPath */ get fullPath(): string { return this.path; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#name */ get name(): string { return pathLastComponent(this.path); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#parent */ get parent(): StorageReference | null { const parentPath = pathParent(this.path); if (parentPath === null) { return parentPath; } return new Reference(this._storage, parentPath); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#root */ get root(): StorageReference { return new Reference(this._storage, '/'); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#storage */ get storage(): FirebaseStorage { return this._storage; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#child */ child(path: string): StorageReference { const childPath = pathChild(this.path, path); return new Reference(this._storage, childPath); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete */ delete(): Promise<void> { return this._storage.native.deleteObject(this.toString()); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL */ getDownloadURL(): Promise<string> { return this._storage.native.getDownloadURL(this.toString()); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getMetadata */ getMetadata(): Promise<FullMetadata> { return this._storage.native.getMetadata(this.toString()); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#list */ list(options?: ListOptions): Promise<StorageListResult> { if (!isUndefined(options) && !isObject(options)) { throw new Error( "firebase.storage.StorageReference.list(*) 'options' expected an object value.", ); } const listOptions: { maxResults: number; pageToken?: string } = { maxResults: 1000, }; if (options) { if (hasOwnProperty(options, 'maxResults')) { const maxResults = options.maxResults; if (maxResults === null || isUndefined(maxResults)) { // no-op (keep default) } else { if (!isNumber(maxResults) || !isInteger(maxResults)) { throw new Error( "firebase.storage.StorageReference.list(*) 'options.maxResults' expected a number value.", ); } if (maxResults < 1 || maxResults > 1000) { throw new Error( "firebase.storage.StorageReference.list(*) 'options.maxResults' expected a number value between 1-1000.", ); } listOptions.maxResults = maxResults; } } if (hasOwnProperty(options, 'pageToken')) { const pageToken = options.pageToken; if (pageToken === null || isUndefined(pageToken)) { // no-op } else if (!isUndefined(pageToken) && pageToken !== null) { if (!isString(pageToken)) { throw new Error( "firebase.storage.StorageReference.list(*) 'options.pageToken' expected a string value.", ); } listOptions.pageToken = pageToken; } } } return this._storage.native .list(this.toString(), listOptions) .then((data: ListResultInternal) => new StorageListResult(this._storage, data)); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#listAll */ listAll(): Promise<StorageListResult> { return this._storage.native .listAll(this.toString()) .then((data: ListResultInternal) => new StorageListResult(this._storage, data)); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#put */ put(data: Blob | Uint8Array | ArrayBuffer, metadata?: UploadMetadata): Task { const validatedMetadata = isUndefined(metadata) ? metadata : validateMetadata(metadata, false); return new StorageUploadTask(this, task => Base64.fromData(data).then(({ string, format }) => { const { _string, _format, _metadata } = this._updateString( string as string, format, validatedMetadata, false, ); return this._storage.native.putString( this.toString(), _string, _format, _metadata, task._id, ); }), ); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putString */ putString( string: string, format: (typeof StringFormat)[keyof typeof StringFormat] = StringFormat.RAW, metadata?: UploadMetadata, ): Task { const { _string, _format, _metadata } = this._updateString(string, format, metadata, false); return new StorageUploadTask(this, task => this._storage.native.putString(this.toString(), _string, _format, _metadata, task._id), ); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#fullPath */ toString(): string { if (this.path.length <= 1) { return `${this._storage._customUrlOrRegion}`; } return `${this._storage._customUrlOrRegion}/${this.path}`; } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#updateMetadata */ updateMetadata(metadata: SettableMetadata): Promise<FullMetadata> { const validatedMetadata = validateMetadata(metadata); return this._storage.native.updateMetadata(this.toString(), validatedMetadata); } /* ---------------------------------------- * EXTRA APIS (DO NOT ON EXIST WEB SDK) * ---------------------------------------- */ /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference */ writeToFile(filePath: string): Task { if (!isString(filePath)) { throw new Error( "firebase.storage.StorageReference.writeToFile(*) 'filePath' expects a string value.", ); } return new StorageDownloadTask(this, task => this._storage.native.writeToFile(this.toString(), toFilePath(filePath), task._id), ); } /** * @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference */ putFile(filePath: string, metadata?: UploadMetadata): Task { const validatedMetadata = isUndefined(metadata) ? metadata : validateMetadata(metadata, false); if (!isString(filePath)) { throw new Error( "firebase.storage.StorageReference.putFile(*, _) 'filePath' expects a string value.", ); } return new StorageUploadTask(this, task => this._storage.native.putFile( this.toString(), toFilePath(filePath), validatedMetadata, task._id, ), ); } _updateString( string: string, format: (typeof StringFormat)[keyof typeof StringFormat], metadata: UploadMetadata | undefined, update = false, ): { _string: string; _format: string; _metadata: UploadMetadata | undefined } { if (!isString(string)) { throw new Error( "firebase.storage.StorageReference.putString(*, _, _) 'string' expects a string value.", ); } if (!Object.values(StringFormat).includes(format)) { throw new Error( `firebase.storage.StorageReference.putString(_, *, _) 'format' provided is invalid, must be one of ${Object.values( StringFormat, ).join(',')}.`, ); } if (!isUndefined(metadata)) { metadata = validateMetadata(metadata, update) as UploadMetadata; } let _string = string; let _format = format; let _metadata = metadata; if (format === StringFormat.RAW) { _string = Base64.btoa(_string); _format = StringFormat.BASE64; } else if (format === StringFormat.DATA_URL) { const { mediaType, base64String } = getDataUrlParts(_string); if (isUndefined(base64String)) { throw new Error( 'firebase.storage.StorageReference.putString(*, _, _) invalid data_url string provided.', ); } if (isUndefined(metadata) || isUndefined(metadata.contentType)) { if (isUndefined(metadata)) { _metadata = {}; } _metadata!.contentType = mediaType; _string = base64String; _format = StringFormat.BASE64; } } return { _string, _metadata, _format }; } } provideStorageReferenceClass(Reference);