storage - js

This commit is contained in:
Salakar 2017-02-14 11:31:42 +00:00
commit e9f9b74b91
3 changed files with 283 additions and 0 deletions

View File

@ -0,0 +1,110 @@
/* @flow */
import { NativeModules, NativeEventEmitter } from 'react-native';
import { Base } from './../base';
import StorageRef from './reference';
const FirebaseStorage = NativeModules.FirebaseStorage;
const FirebaseStorageEvt = new NativeEventEmitter(FirebaseStorage);
type StorageOptionsType = {
storageBucket?: ?string,
};
export default class Storage extends Base {
constructor(firebase: Object, options: StorageOptionsType = {}) {
super(firebase, options);
this.subscriptions = {};
this.successListener = FirebaseStorageEvt.addListener(
'storage_event',
event => this._handleStorageEvent(event)
);
this.errorListener = FirebaseStorageEvt.addListener(
'storage_error',
err => this._handleStorageError(err)
);
}
ref(path: string): StorageRef {
return new StorageRef(this, path);
}
refFromURL(url: string): Promise<StorageRef> {
return new StorageRef(this, `url::${url}`);
}
setMaxOperationRetryTime(time: number) {
FirebaseStorage.setMaxOperationRetryTime(time);
}
setMaxUploadRetryTime(time: number) {
FirebaseStorage.setMaxUploadRetryTime(time);
}
// additional methods compared to Web API
setMaxDownloadRetryTime(time: number) {
FirebaseStorage.setMaxDownloadRetryTime(time);
}
_handleStorageEvent(event: Object) {
const { path, eventName } = event;
const body = event.body || {};
this.log.debug('_handleStorageEvent: ', path, eventName, body);
if (this.subscriptions[path] && this.subscriptions[path][eventName]) {
this.subscriptions[path][eventName].forEach((cb) => {
cb(body);
});
}
}
_handleStorageError(err: Object) {
this.log.debug('_handleStorageError ->', err);
}
_addListener(path: string, eventName: string, cb: (evt: Object) => Object) {
if (!this.subscriptions[path]) this.subscriptions[path] = {};
if (!this.subscriptions[path][eventName]) this.subscriptions[path][eventName] = [];
this.subscriptions[path][eventName].push(cb);
}
_removeListener(path: string, eventName: string, origCB: (evt: Object) => Object) {
if (!this.subscriptions[path] || (eventName && !this.subscriptions[path][eventName])) {
this.log.warn('_removeListener() called, but not currently listening at that location (bad path)', path, eventName);
return;
}
if (eventName && origCB) {
const i = this.subscriptions[path][eventName].indexOf(origCB);
if (i === -1) {
this.log.warn('_removeListener() called, but the callback specified is not listening at this location (bad path)', path, eventName);
} else {
this.subscriptions[path][eventName].splice(i, 1);
}
} else if (eventName) {
this.subscriptions[path][eventName] = [];
} else {
this.subscriptions[path] = {};
}
}
static constants = {
MAIN_BUNDLE_PATH: FirebaseStorage.MAIN_BUNDLE_PATH,
CACHES_DIRECTORY_PATH: FirebaseStorage.CACHES_DIRECTORY_PATH,
DOCUMENT_DIRECTORY_PATH: FirebaseStorage.DOCUMENT_DIRECTORY_PATH,
EXTERNAL_DIRECTORY_PATH: FirebaseStorage.EXTERNAL_DIRECTORY_PATH,
EXTERNAL_STORAGE_DIRECTORY_PATH: FirebaseStorage.EXTERNAL_STORAGE_DIRECTORY_PATH,
TEMP_DIRECTORY_PATH: FirebaseStorage.TEMP_DIRECTORY_PATH,
LIBRARY_DIRECTORY_PATH: FirebaseStorage.LIBRARY_DIRECTORY_PATH,
FILETYPE_REGULAR: FirebaseStorage.FILETYPE_REGULAR,
FILETYPE_DIRECTORY: FirebaseStorage.FILETYPE_DIRECTORY,
};
get namespace(): string {
return 'firebase:storage';
}
}

View File

@ -0,0 +1,119 @@
/* @flow */
import { NativeModules } from 'react-native';
import { promisify } from '../../utils';
import { ReferenceBase } from './../base';
import StorageTask, { UPLOAD_TASK, DOWNLOAD_TASK } from './task';
import Storage from './';
const FirebaseStorage = NativeModules.FirebaseStorage;
/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference
*/
export default class StorageReference extends ReferenceBase {
constructor(storage: Storage, path: string) {
super(storage.firebase, path);
this.storage = storage;
}
get fullPath() {
return this.path;
}
// todo add support for method
put(data: Object, metadata: Object = {}): /*UploadTask*/Promise<Object> {
throw new Error('put() is not currently supported by react-native-firebase');
}
// todo add support for method
putString(data: string, format: String, metadata: Object = {}): /*UploadTask*/Promise<Object> {
throw new Error('putString() is not currently supported by react-native-firebase');
}
// todo eturn full gs://bucket/path
toString(): String {
return this.path;
}
/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#child
* @param path
* @returns {StorageReference}
*/
child(path: string) {
return new StorageReference(this.storage, `${this.path}/${path}`);
}
/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete
* @returns {Promise.<T>|*}
*/
delete(): Promise {
return promisify('delete', FirebaseStorage)(this.path)
.catch((error) => {
this.log.error('Error deleting reference ', this.path, '. Error: ', error);
throw error;
});
}
/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL
* @returns {Promise.<T>|*}
*/
getDownloadURL(): Promise<String> {
this.log.debug('getDownloadURL(', this.path, ')');
return promisify('getDownloadURL', FirebaseStorage)(this.path)
.catch((err) => {
this.log.error('Error downloading URL for ', this.path, '. Error: ', err);
throw err;
});
}
/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getMetadata
* @returns {Promise.<T>|*}
*/
getMetadata(): Promise<Object> {
return promisify('getMetadata', FirebaseStorage)(this.path)
.catch((error) => {
this.log.error('Error getting metadata for ', this.path, '. Error: ', error);
throw error;
});
}
/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#updateMetadata
* @param metadata
* @returns {Promise.<T>|*}
*/
updateMetadata(metadata: Object = {}): Promise<Object> {
return promisify('updateMetadata', FirebaseStorage)(this.path, metadata)
.catch((error) => {
this.log.error('Error updating metadata for ', this.path, '. Error: ', error);
throw error;
});
}
/**
* Downloads a reference to the device
* @param {String} filePath Where to store the file
* @return {Promise}
*/
downloadFile(filePath: string): Promise<Object> {
this.log.debug('download(', this.path, ') -> ', filePath);
return new StorageTask(DOWNLOAD_TASK, promisify('downloadFile', FirebaseStorage)(this.path, filePath), this);
}
/**
* Upload a file path
* @param {string} filePath The local path of the file
* @param {object} metadata An object containing metadata
* @return {Promise}
*/
putFile(filePath: Object, metadata: Object = {}): Promise<Object> {
const _filePath = filePath.replace('file://', '');
this.log.debug('putFile(', _filePath, ') -> ', this.path);
return new StorageTask(UPLOAD_TASK, promisify('putFile', FirebaseStorage)(this.path, _filePath, metadata), this);
}
}

View File

@ -0,0 +1,54 @@
export const UPLOAD_TASK = 'upload';
export const DOWNLOAD_TASK = 'download';
/**
* @url https://firebase.google.com/docs/reference/js/firebase.storage.UploadTask
*/
export default class StorageTask {
constructor(type: string, promise, storageRef) {
this.type = type;
this.ref = storageRef;
this.promise = promise;
this.storage = storageRef.storage;
// 'proxy' original promise
this.then = promise.then;
this.catch = promise.catch;
}
/**
*
* @param event
* @param nextOrObserver
* @param error
* @param complete
* @returns {function()}
*/
on(event = 'state_changed', nextOrObserver, error, complete) {
if (nextOrObserver) this.storage._addListener(this.path, 'state_changed', nextOrObserver);
if (error) this.storage._addListener(this.path, `${this.type}_failure`, error);
if (complete) this.storage._addListener(this.path, `${this.type}_success`, complete);
// off
// todo support add callback syntax as per https://firebase.google.com/docs/reference/js/firebase.storage.UploadTask#on
return () => {
if (nextOrObserver) this.storage._removeListener(this.path, 'state_changed', nextOrObserver);
if (error) this.storage._removeListener(this.path, `${this.type}_failure`, error);
if (complete) this.storage._removeListener(this.path, `${this.type}_success`, complete);
};
}
pause() {
// todo
throw new Error('.pause() is not currently supported by react-native-firebase');
}
resume() {
// todo
throw new Error('.resume() is not currently supported by react-native-firebase');
}
cancel() {
// todo
throw new Error('.cancel() is not currently supported by react-native-firebase');
}
}