[types] Get flow type working again; Fix majority of firestore type issues
This commit is contained in:
parent
5c43c88f6a
commit
8bd9684644
@ -34,7 +34,13 @@
|
|||||||
"import/extensions": 0,
|
"import/extensions": 0,
|
||||||
"import/no-unresolved": 0,
|
"import/no-unresolved": 0,
|
||||||
"import/no-extraneous-dependencies": 0,
|
"import/no-extraneous-dependencies": 0,
|
||||||
"react/jsx-filename-extension": 0
|
"react/jsx-filename-extension": 0,
|
||||||
|
"no-unused-expressions": 0,
|
||||||
|
"flowtype/no-unused-expressions": ['error', {
|
||||||
|
allowShortCircuit: false,
|
||||||
|
allowTernary: false,
|
||||||
|
allowTaggedTemplates: false,
|
||||||
|
}]
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"__DEV__": true,
|
"__DEV__": true,
|
||||||
|
@ -91,7 +91,7 @@ unsafe.enable_getters_and_setters=true
|
|||||||
esproposal.class_static_fields=enable
|
esproposal.class_static_fields=enable
|
||||||
esproposal.class_instance_fields=enable
|
esproposal.class_instance_fields=enable
|
||||||
|
|
||||||
munge_underscores=true
|
munge_underscores=false
|
||||||
|
|
||||||
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
|
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
|
||||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
||||||
@ -105,4 +105,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-4]\\|1[0-9]\\|[0-9
|
|||||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||||
|
|
||||||
[version]
|
[version]
|
||||||
^0.46.0
|
^0.56.0
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
import { NativeModules } from 'react-native';
|
import { NativeModules } from 'react-native';
|
||||||
|
|
||||||
import INTERNALS from './internals';
|
import INTERNALS from './internals';
|
||||||
@ -16,10 +19,31 @@ import Firestore, { statics as FirestoreStatics } from './modules/firestore';
|
|||||||
import Links, { statics as LinksStatics } from './modules/links';
|
import Links, { statics as LinksStatics } from './modules/links';
|
||||||
import Utils, { statics as UtilsStatics } from './modules/utils';
|
import Utils, { statics as UtilsStatics } from './modules/utils';
|
||||||
|
|
||||||
|
import type { FirebaseOptions } from './firebase';
|
||||||
|
|
||||||
const FirebaseCoreModule = NativeModules.RNFirebase;
|
const FirebaseCoreModule = NativeModules.RNFirebase;
|
||||||
|
|
||||||
export default class FirebaseApp {
|
export default class FirebaseApp {
|
||||||
constructor(name: string, options: Object = {}) {
|
_extendedProps: { [string] : boolean };
|
||||||
|
_initialized: boolean;
|
||||||
|
_name: string;
|
||||||
|
_namespaces: { [string]: Object };
|
||||||
|
_nativeInitialized: boolean;
|
||||||
|
_options: FirebaseOptions;
|
||||||
|
admob: () => AdMob;
|
||||||
|
auth: () => Auth;
|
||||||
|
analytics: () => Analytics;
|
||||||
|
config: () => RemoteConfig;
|
||||||
|
crash: () => Crash;
|
||||||
|
database: () => Database;
|
||||||
|
firestore: () => Firestore;
|
||||||
|
links: () => Links;
|
||||||
|
messaging: () => Messaging;
|
||||||
|
perf: () => Performance;
|
||||||
|
storage: () => Storage;
|
||||||
|
utils: () => Utils;
|
||||||
|
|
||||||
|
constructor(name: string, options: FirebaseOptions) {
|
||||||
this._name = name;
|
this._name = name;
|
||||||
this._namespaces = {};
|
this._namespaces = {};
|
||||||
this._options = Object.assign({}, options);
|
this._options = Object.assign({}, options);
|
||||||
@ -49,7 +73,7 @@ export default class FirebaseApp {
|
|||||||
* @param native
|
* @param native
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_initializeApp(native = false) {
|
_initializeApp(native: boolean = false) {
|
||||||
if (native) {
|
if (native) {
|
||||||
// for apps already initialized natively that
|
// for apps already initialized natively that
|
||||||
// we have info from RN constants
|
// we have info from RN constants
|
||||||
@ -67,7 +91,7 @@ export default class FirebaseApp {
|
|||||||
*
|
*
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
get name() {
|
get name(): string {
|
||||||
if (this._name === INTERNALS.STRINGS.DEFAULT_APP_NAME) {
|
if (this._name === INTERNALS.STRINGS.DEFAULT_APP_NAME) {
|
||||||
// ios and android firebase sdk's return different
|
// ios and android firebase sdk's return different
|
||||||
// app names - so we just return what the web sdk
|
// app names - so we just return what the web sdk
|
||||||
@ -82,7 +106,7 @@ export default class FirebaseApp {
|
|||||||
*
|
*
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
get options() {
|
get options(): FirebaseOptions {
|
||||||
return Object.assign({}, this._options);
|
return Object.assign({}, this._options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,14 +119,14 @@ export default class FirebaseApp {
|
|||||||
* @param props
|
* @param props
|
||||||
*/
|
*/
|
||||||
extendApp(props: Object) {
|
extendApp(props: Object) {
|
||||||
if (!isObject(props)) throw new Error(INTERNALS.ERROR_MISSING_ARG('Object', 'extendApp'));
|
if (!isObject(props)) throw new Error(INTERNALS.STRINGS.ERROR_MISSING_ARG('Object', 'extendApp'));
|
||||||
const keys = Object.keys(props);
|
const keys = Object.keys(props);
|
||||||
|
|
||||||
for (let i = 0, len = keys.length; i < len; i++) {
|
for (let i = 0, len = keys.length; i < len; i++) {
|
||||||
const key = keys[i];
|
const key = keys[i];
|
||||||
|
|
||||||
if (!this._extendedProps[key] && Object.hasOwnProperty.call(this, key)) {
|
if (!this._extendedProps[key] && Object.hasOwnProperty.call(this, key)) {
|
||||||
throw new Error(INTERNALS.ERROR_PROTECTED_PROP(key));
|
throw new Error(INTERNALS.STRINGS.ERROR_PROTECTED_PROP(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
this[key] = props[key];
|
this[key] = props[key];
|
||||||
@ -131,7 +155,7 @@ export default class FirebaseApp {
|
|||||||
*
|
*
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
onReady(): Promise {
|
onReady(): Promise<FirebaseApp> {
|
||||||
if (this._initialized) return Promise.resolve(this);
|
if (this._initialized) return Promise.resolve(this);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -144,13 +168,12 @@ export default class FirebaseApp {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param name
|
|
||||||
* @param statics
|
* @param statics
|
||||||
* @param InstanceClass
|
* @param InstanceClass
|
||||||
* @return {function()}
|
* @return {function()}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_staticsOrModuleInstance(statics = {}, InstanceClass): Function {
|
_staticsOrModuleInstance(statics: Object = {}, InstanceClass: Class<*>) {
|
||||||
const getInstance = () => {
|
const getInstance = () => {
|
||||||
const _name = `_${InstanceClass._NAMESPACE}`;
|
const _name = `_${InstanceClass._NAMESPACE}`;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { NativeModules, NativeEventEmitter } from 'react-native';
|
|||||||
|
|
||||||
import INTERNALS from './internals';
|
import INTERNALS from './internals';
|
||||||
import FirebaseApp from './firebase-app';
|
import FirebaseApp from './firebase-app';
|
||||||
import { isObject, isString, isAndroid } from './utils';
|
import { isObject, isString } from './utils';
|
||||||
|
|
||||||
// module imports
|
// module imports
|
||||||
import AdMob, { statics as AdMobStatics } from './modules/admob';
|
import AdMob, { statics as AdMobStatics } from './modules/admob';
|
||||||
@ -24,7 +24,31 @@ import Utils, { statics as UtilsStatics } from './modules/utils';
|
|||||||
|
|
||||||
const FirebaseCoreModule = NativeModules.RNFirebase;
|
const FirebaseCoreModule = NativeModules.RNFirebase;
|
||||||
|
|
||||||
|
export type FirebaseOptions = {
|
||||||
|
apiKey: string,
|
||||||
|
appId: string,
|
||||||
|
databaseURL: string,
|
||||||
|
messagingSenderId: string,
|
||||||
|
projectId: string,
|
||||||
|
storageBucket: string,
|
||||||
|
}
|
||||||
|
|
||||||
class FirebaseCore {
|
class FirebaseCore {
|
||||||
|
_nativeEmitters: { [string]: NativeEventEmitter };
|
||||||
|
_nativeSubscriptions: { [string]: boolean };
|
||||||
|
admob: () => AdMob;
|
||||||
|
auth: () => Auth;
|
||||||
|
analytics: () => Analytics;
|
||||||
|
config: () => RemoteConfig;
|
||||||
|
crash: () => Crash;
|
||||||
|
database: () => Database;
|
||||||
|
firestore: () => Firestore;
|
||||||
|
links: () => Links;
|
||||||
|
messaging: () => Messaging;
|
||||||
|
perf: () => Performance;
|
||||||
|
storage: () => Storage;
|
||||||
|
utils: () => Utils;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._nativeEmitters = {};
|
this._nativeEmitters = {};
|
||||||
this._nativeSubscriptions = {};
|
this._nativeSubscriptions = {};
|
||||||
@ -71,7 +95,7 @@ class FirebaseCore {
|
|||||||
* @param name
|
* @param name
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
initializeApp(options: Object = {}, name: string): FirebaseApp {
|
initializeApp(options: FirebaseOptions, name: string): FirebaseApp {
|
||||||
if (name && !isString(name)) {
|
if (name && !isString(name)) {
|
||||||
throw new Error(INTERNALS.STRINGS.ERROR_INIT_STRING_NAME);
|
throw new Error(INTERNALS.STRINGS.ERROR_INIT_STRING_NAME);
|
||||||
}
|
}
|
||||||
@ -163,7 +187,7 @@ class FirebaseCore {
|
|||||||
* @param nativeEmitter
|
* @param nativeEmitter
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_subscribeForDistribution(eventName, nativeEmitter) {
|
_subscribeForDistribution(eventName: string, nativeEmitter: NativeEventEmitter) {
|
||||||
if (!this._nativeSubscriptions[eventName]) {
|
if (!this._nativeSubscriptions[eventName]) {
|
||||||
nativeEmitter.addListener(eventName, (event) => {
|
nativeEmitter.addListener(eventName, (event) => {
|
||||||
if (event.appName) {
|
if (event.appName) {
|
||||||
@ -186,7 +210,7 @@ class FirebaseCore {
|
|||||||
* @return {function(FirebaseApp=)}
|
* @return {function(FirebaseApp=)}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_appNamespaceOrStatics(statics = {}, InstanceClass): Function {
|
_appNamespaceOrStatics(statics: Object = {}, InstanceClass: Class<*>): Function {
|
||||||
const namespace = InstanceClass._NAMESPACE;
|
const namespace = InstanceClass._NAMESPACE;
|
||||||
|
|
||||||
const getNamespace = (app?: FirebaseApp) => {
|
const getNamespace = (app?: FirebaseApp) => {
|
||||||
@ -215,14 +239,13 @@ class FirebaseCore {
|
|||||||
* @return {*}
|
* @return {*}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_getOrSetNativeEmitter(name, nativeModule) {
|
_getOrSetNativeEmitter(name: string, nativeModule: Object): NativeEventEmitter {
|
||||||
if (this._nativeEmitters[name]) {
|
if (this._nativeEmitters[name]) {
|
||||||
return this._nativeEmitters[name];
|
return this._nativeEmitters[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._nativeEmitters[name] = new NativeEventEmitter(nativeModule);
|
return this._nativeEmitters[name] = new NativeEventEmitter(nativeModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new FirebaseCore();
|
export default new FirebaseCore();
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
import { Platform, NativeModules } from 'react-native';
|
import { Platform, NativeModules } from 'react-native';
|
||||||
|
|
||||||
import EventEmitter from './utils/emitter/EventEmitter';
|
import EventEmitter from './utils/emitter/EventEmitter';
|
||||||
|
import ModuleBase from './utils/ModuleBase';
|
||||||
import SyncTree from './utils/SyncTree';
|
import SyncTree from './utils/SyncTree';
|
||||||
|
|
||||||
const DEFAULT_APP_NAME = Platform.OS === 'ios' ? '__FIRAPP_DEFAULT' : '[DEFAULT]';
|
const DEFAULT_APP_NAME = Platform.OS === 'ios' ? '__FIRAPP_DEFAULT' : '[DEFAULT]';
|
||||||
@ -92,35 +96,35 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_MISSING_CB(method) {
|
ERROR_MISSING_CB(method: string) {
|
||||||
return `Missing required callback for method ${method}().`;
|
return `Missing required callback for method ${method}().`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_MISSING_ARG(type, method) {
|
ERROR_MISSING_ARG(type: string, method: string) {
|
||||||
return `Missing required argument of type '${type}' for method '${method}()'.`;
|
return `Missing required argument of type '${type}' for method '${method}()'.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_MISSING_ARG_NAMED(name, type, method) {
|
ERROR_MISSING_ARG_NAMED(name: string, type: string, method: string) {
|
||||||
return `Missing required argument '${name}' of type '${type}' for method '${method}()'.`;
|
return `Missing required argument '${name}' of type '${type}' for method '${method}()'.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_ARG_INVALID_VALUE(name, expected, got) {
|
ERROR_ARG_INVALID_VALUE(name: string, expected: string, got: string) {
|
||||||
return `Invalid value for argument '${name}' expected value '${expected}' but got '${got}'.`;
|
return `Invalid value for argument '${name}' expected value '${expected}' but got '${got}'.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_PROTECTED_PROP(name) {
|
ERROR_PROTECTED_PROP(name: string) {
|
||||||
return `Property '${name}' is protected and can not be overridden by extendApp.`;
|
return `Property '${name}' is protected and can not be overridden by extendApp.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -129,7 +133,7 @@ export default {
|
|||||||
* @param namespace
|
* @param namespace
|
||||||
* @param nativeModule
|
* @param nativeModule
|
||||||
*/
|
*/
|
||||||
ERROR_MISSING_MODULE(namespace, nativeModule) {
|
ERROR_MISSING_MODULE(namespace: string, nativeModule: string) {
|
||||||
const snippet = `firebase.${namespace}()`;
|
const snippet = `firebase.${namespace}()`;
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
return `You attempted to use a firebase module that's not installed natively on your iOS project by calling ${snippet}.` +
|
return `You attempted to use a firebase module that's not installed natively on your iOS project by calling ${snippet}.` +
|
||||||
@ -151,7 +155,7 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_APP_NOT_INIT(appName) {
|
ERROR_APP_NOT_INIT(appName: string) {
|
||||||
return `The [${appName}] firebase app has not been initialized!`;
|
return `The [${appName}] firebase app has not been initialized!`;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -160,35 +164,35 @@ export default {
|
|||||||
* @return {string}
|
* @return {string}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
ERROR_MISSING_OPT(optName) {
|
ERROR_MISSING_OPT(optName: string) {
|
||||||
return `Failed to initialize app. FirebaseOptions missing or invalid '${optName}' property.`;
|
return `Failed to initialize app. FirebaseOptions missing or invalid '${optName}' property.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_NOT_APP(namespace) {
|
ERROR_NOT_APP(namespace: string) {
|
||||||
return `Invalid FirebaseApp instance passed to firebase.${namespace}(app <--).`;
|
return `Invalid FirebaseApp instance passed to firebase.${namespace}(app <--).`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_UNSUPPORTED_CLASS_METHOD(className, method) {
|
ERROR_UNSUPPORTED_CLASS_METHOD(className: string, method: string) {
|
||||||
return `${className}.${method}() is unsupported by the native Firebase SDKs.`;
|
return `${className}.${method}() is unsupported by the native Firebase SDKs.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_UNSUPPORTED_CLASS_PROPERTY(className, property) {
|
ERROR_UNSUPPORTED_CLASS_PROPERTY(className: string, property: string) {
|
||||||
return `${className}.${property} is unsupported by the native Firebase SDKs.`;
|
return `${className}.${property} is unsupported by the native Firebase SDKs.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_UNSUPPORTED_MODULE_METHOD(module, method) {
|
ERROR_UNSUPPORTED_MODULE_METHOD(module: Class<ModuleBase>, method: string) {
|
||||||
return `firebase.${module._NAMESPACE}().${method}() is unsupported by the native Firebase SDKs.`;
|
return `firebase.${module._NAMESPACE}().${method}() is unsupported by the native Firebase SDKs.`;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -196,7 +200,7 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
ERROR_PLAY_SERVICES(statusCode) {
|
ERROR_PLAY_SERVICES(statusCode: number) {
|
||||||
const knownError = PLAY_SERVICES_CODES[statusCode];
|
const knownError = PLAY_SERVICES_CODES[statusCode];
|
||||||
let start = 'Google Play Services is required to run firebase services on android but a valid installation was not found on this device.';
|
let start = 'Google Play Services is required to run firebase services on android but a valid installation was not found on this device.';
|
||||||
|
|
||||||
@ -208,8 +212,8 @@ export default {
|
|||||||
return `${start}\r\n\r\n` +
|
return `${start}\r\n\r\n` +
|
||||||
'-------------------------\r\n' +
|
'-------------------------\r\n' +
|
||||||
(knownError ?
|
(knownError ?
|
||||||
`${knownError.code}: ${knownError.message} (code ${statusCode})` :
|
`${knownError.code}: ${knownError.message} (code ${statusCode})` :
|
||||||
`A specific play store availability reason reason was not available (unknown code: ${statusCode || null})`
|
`A specific play store availability reason reason was not available (unknown code: ${statusCode})`
|
||||||
) +
|
) +
|
||||||
'\r\n-------------------------' +
|
'\r\n-------------------------' +
|
||||||
'\r\n\r\n' +
|
'\r\n\r\n' +
|
||||||
@ -226,9 +230,9 @@ export default {
|
|||||||
SyncTree: NativeModules.RNFirebaseDatabase ? new SyncTree(NativeModules.RNFirebaseDatabase) : null,
|
SyncTree: NativeModules.RNFirebaseDatabase ? new SyncTree(NativeModules.RNFirebaseDatabase) : null,
|
||||||
|
|
||||||
// internal utils
|
// internal utils
|
||||||
deleteApp(name: String) {
|
deleteApp(name: String): Promise<boolean> {
|
||||||
const app = this.APPS[name];
|
const app = this.APPS[name];
|
||||||
if (!app) return Promise.resolve();
|
if (!app) return Promise.resolve(true);
|
||||||
|
|
||||||
// https://firebase.google.com/docs/reference/js/firebase.app.App#delete
|
// https://firebase.google.com/docs/reference/js/firebase.app.App#delete
|
||||||
return app.delete().then(() => {
|
return app.delete().then(() => {
|
||||||
|
@ -3,19 +3,19 @@
|
|||||||
* CollectionReference representation wrapper
|
* CollectionReference representation wrapper
|
||||||
*/
|
*/
|
||||||
import DocumentReference from './DocumentReference';
|
import DocumentReference from './DocumentReference';
|
||||||
import Path from './Path';
|
import Query, { type Direction, type Operator } from './Query';
|
||||||
import Query from './Query';
|
|
||||||
import QuerySnapshot from './QuerySnapshot';
|
|
||||||
import { firestoreAutoId } from '../../utils';
|
import { firestoreAutoId } from '../../utils';
|
||||||
|
|
||||||
import type { Direction, Operator } from './Query';
|
import type Firestore from './';
|
||||||
|
import type Path from './Path';
|
||||||
|
import type QuerySnapshot from './QuerySnapshot';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class CollectionReference
|
* @class CollectionReference
|
||||||
*/
|
*/
|
||||||
export default class CollectionReference {
|
export default class CollectionReference {
|
||||||
_collectionPath: Path;
|
_collectionPath: Path;
|
||||||
_firestore: Object;
|
_firestore: Firestore;
|
||||||
_query: Query;
|
_query: Query;
|
||||||
|
|
||||||
constructor(firestore: Object, collectionPath: Path) {
|
constructor(firestore: Object, collectionPath: Path) {
|
||||||
@ -71,10 +71,6 @@ export default class CollectionReference {
|
|||||||
return this._query.limit(n);
|
return this._query.limit(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset(n: number): Query {
|
|
||||||
return this._query.offset(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSnapshot(onNext: () => any, onError?: () => any): () => void {
|
onSnapshot(onNext: () => any, onError?: () => any): () => void {
|
||||||
return this._query.onSnapshot(onNext, onError);
|
return this._query.onSnapshot(onNext, onError);
|
||||||
}
|
}
|
||||||
@ -91,10 +87,6 @@ export default class CollectionReference {
|
|||||||
return this._query.startAt(fieldValues);
|
return this._query.startAt(fieldValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream(): Stream<DocumentSnapshot> {
|
|
||||||
return this._query.stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
where(fieldPath: string, opStr: Operator, value: any): Query {
|
where(fieldPath: string, opStr: Operator, value: any): Query {
|
||||||
return this._query.where(fieldPath, opStr, value);
|
return this._query.where(fieldPath, opStr, value);
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,19 @@
|
|||||||
* @flow
|
* @flow
|
||||||
* DocumentChange representation wrapper
|
* DocumentChange representation wrapper
|
||||||
*/
|
*/
|
||||||
import DocumentSnapshot from './DocumentSnapshot';
|
import DocumentSnapshot, { type DocumentSnapshotNativeData } from './DocumentSnapshot';
|
||||||
|
|
||||||
|
import type Firestore from './';
|
||||||
|
|
||||||
|
|
||||||
export type DocumentChangeNativeData = {
|
export type DocumentChangeNativeData = {
|
||||||
document: DocumentSnapshot,
|
document: DocumentSnapshotNativeData,
|
||||||
newIndex: number,
|
newIndex: number,
|
||||||
oldIndex: number,
|
oldIndex: number,
|
||||||
type: string,
|
type: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class DocumentChange
|
* @class DocumentChange
|
||||||
*/
|
*/
|
||||||
export default class DocumentChange {
|
export default class DocumentChange {
|
||||||
@ -21,7 +23,7 @@ export default class DocumentChange {
|
|||||||
_oldIndex: number;
|
_oldIndex: number;
|
||||||
_type: string;
|
_type: string;
|
||||||
|
|
||||||
constructor(firestore: Object, nativeData: DocumentChangeNativeData) {
|
constructor(firestore: Firestore, nativeData: DocumentChangeNativeData) {
|
||||||
this._document = new DocumentSnapshot(firestore, nativeData.document);
|
this._document = new DocumentSnapshot(firestore, nativeData.document);
|
||||||
this._newIndex = nativeData.newIndex;
|
this._newIndex = nativeData.newIndex;
|
||||||
this._oldIndex = nativeData.oldIndex;
|
this._oldIndex = nativeData.oldIndex;
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
* DocumentReference representation wrapper
|
* DocumentReference representation wrapper
|
||||||
*/
|
*/
|
||||||
import CollectionReference from './CollectionReference';
|
import CollectionReference from './CollectionReference';
|
||||||
import DocumentSnapshot from './DocumentSnapshot';
|
import DocumentSnapshot, { type DocumentSnapshotNativeData } from './DocumentSnapshot';
|
||||||
import Path from './Path';
|
|
||||||
import { buildNativeMap } from './utils/serialize';
|
import { buildNativeMap } from './utils/serialize';
|
||||||
import { firestoreAutoId, isFunction, isObject, isString } from '../../utils';
|
import { firestoreAutoId, isFunction, isObject, isString } from '../../utils';
|
||||||
|
|
||||||
|
import type Firestore from './';
|
||||||
|
import type Path from './Path';
|
||||||
|
|
||||||
export type WriteOptions = {
|
export type WriteOptions = {
|
||||||
merge?: boolean,
|
merge?: boolean,
|
||||||
}
|
}
|
||||||
@ -16,24 +18,27 @@ type DocumentListenOptions = {
|
|||||||
includeMetadataChanges: boolean,
|
includeMetadataChanges: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ObserverOnError = (Object) => void;
|
||||||
|
type ObserverOnNext = (DocumentSnapshot) => void;
|
||||||
|
|
||||||
type Observer = {
|
type Observer = {
|
||||||
next: (DocumentSnapshot) => void,
|
error?: ObserverOnError,
|
||||||
error?: (Object) => void,
|
next: ObserverOnNext,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class DocumentReference
|
* @class DocumentReference
|
||||||
*/
|
*/
|
||||||
export default class DocumentReference {
|
export default class DocumentReference {
|
||||||
_documentPath: Path;
|
_documentPath: Path;
|
||||||
_firestore: Object;
|
_firestore: Firestore;
|
||||||
|
|
||||||
constructor(firestore: Object, documentPath: Path) {
|
constructor(firestore: Firestore, documentPath: Path) {
|
||||||
this._documentPath = documentPath;
|
this._documentPath = documentPath;
|
||||||
this._firestore = firestore;
|
this._firestore = firestore;
|
||||||
}
|
}
|
||||||
|
|
||||||
get firestore(): Object {
|
get firestore(): Firestore {
|
||||||
return this._firestore;
|
return this._firestore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +48,9 @@ export default class DocumentReference {
|
|||||||
|
|
||||||
get parent(): CollectionReference {
|
get parent(): CollectionReference {
|
||||||
const parentPath = this._documentPath.parent();
|
const parentPath = this._documentPath.parent();
|
||||||
|
if (!parentPath) {
|
||||||
|
throw new Error('Invalid document path');
|
||||||
|
}
|
||||||
return new CollectionReference(this._firestore, parentPath);
|
return new CollectionReference(this._firestore, parentPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,9 +79,9 @@ export default class DocumentReference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSnapshot(
|
onSnapshot(
|
||||||
optionsOrObserverOrOnNext: DocumentListenOptions | Observer | (DocumentSnapshot) => void,
|
optionsOrObserverOrOnNext: DocumentListenOptions | Observer | ObserverOnNext,
|
||||||
observerOrOnNextOrOnError?: Observer | (DocumentSnapshot) => void | (Object) => void,
|
observerOrOnNextOrOnError?: Observer | ObserverOnNext | ObserverOnError,
|
||||||
onError?: (Object) => void
|
onError?: ObserverOnError,
|
||||||
) {
|
) {
|
||||||
let observer = {};
|
let observer = {};
|
||||||
let docListenOptions = {};
|
let docListenOptions = {};
|
||||||
@ -125,8 +133,8 @@ export default class DocumentReference {
|
|||||||
}
|
}
|
||||||
const listenerId = firestoreAutoId();
|
const listenerId = firestoreAutoId();
|
||||||
|
|
||||||
const listener = (nativeDocumentSnapshot) => {
|
const listener = (nativeDocumentSnapshot: DocumentSnapshotNativeData) => {
|
||||||
const documentSnapshot = new DocumentSnapshot(this, nativeDocumentSnapshot);
|
const documentSnapshot = new DocumentSnapshot(this.firestore, nativeDocumentSnapshot);
|
||||||
observer.next(documentSnapshot);
|
observer.next(documentSnapshot);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -158,7 +166,7 @@ export default class DocumentReference {
|
|||||||
.documentSet(this.path, nativeData, writeOptions);
|
.documentSet(this.path, nativeData, writeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(...args: Object | string[]): Promise<void> {
|
update(...args: Array<any>): Promise<void> {
|
||||||
let data = {};
|
let data = {};
|
||||||
if (args.length === 1) {
|
if (args.length === 1) {
|
||||||
if (!isObject(args[0])) {
|
if (!isObject(args[0])) {
|
||||||
@ -190,7 +198,7 @@ export default class DocumentReference {
|
|||||||
* Remove document snapshot listener
|
* Remove document snapshot listener
|
||||||
* @param listener
|
* @param listener
|
||||||
*/
|
*/
|
||||||
_offDocumentSnapshot(listenerId: number, listener: Function) {
|
_offDocumentSnapshot(listenerId: string, listener: Function) {
|
||||||
this._firestore.log.info('Removing onDocumentSnapshot listener');
|
this._firestore.log.info('Removing onDocumentSnapshot listener');
|
||||||
this._firestore.removeListener(this._firestore._getAppEventName(`onDocumentSnapshot:${listenerId}`), listener);
|
this._firestore.removeListener(this._firestore._getAppEventName(`onDocumentSnapshot:${listenerId}`), listener);
|
||||||
this._firestore.removeListener(this._firestore._getAppEventName(`onDocumentSnapshotError:${listenerId}`), listener);
|
this._firestore.removeListener(this._firestore._getAppEventName(`onDocumentSnapshotError:${listenerId}`), listener);
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
import DocumentReference from './DocumentReference';
|
import DocumentReference from './DocumentReference';
|
||||||
import Path from './Path';
|
import Path from './Path';
|
||||||
import { parseNativeMap } from './utils/serialize';
|
import { parseNativeMap, type TypeMap } from './utils/serialize';
|
||||||
|
|
||||||
|
import type Firestore from './';
|
||||||
|
|
||||||
export type SnapshotMetadata = {
|
export type SnapshotMetadata = {
|
||||||
fromCache: boolean,
|
fromCache: boolean,
|
||||||
@ -12,7 +14,7 @@ export type SnapshotMetadata = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type DocumentSnapshotNativeData = {
|
export type DocumentSnapshotNativeData = {
|
||||||
data: Object,
|
data: { [string]: TypeMap },
|
||||||
metadata: SnapshotMetadata,
|
metadata: SnapshotMetadata,
|
||||||
path: string,
|
path: string,
|
||||||
}
|
}
|
||||||
@ -21,11 +23,11 @@ export type DocumentSnapshotNativeData = {
|
|||||||
* @class DocumentSnapshot
|
* @class DocumentSnapshot
|
||||||
*/
|
*/
|
||||||
export default class DocumentSnapshot {
|
export default class DocumentSnapshot {
|
||||||
_data: Object;
|
_data: Object | void;
|
||||||
_metadata: SnapshotMetadata;
|
_metadata: SnapshotMetadata;
|
||||||
_ref: DocumentReference;
|
_ref: DocumentReference;
|
||||||
|
|
||||||
constructor(firestore: Object, nativeData: DocumentSnapshotNativeData) {
|
constructor(firestore: Firestore, nativeData: DocumentSnapshotNativeData) {
|
||||||
this._data = parseNativeMap(firestore, nativeData.data);
|
this._data = parseNativeMap(firestore, nativeData.data);
|
||||||
this._metadata = nativeData.metadata;
|
this._metadata = nativeData.metadata;
|
||||||
this._ref = new DocumentReference(firestore, Path.fromName(nativeData.path));
|
this._ref = new DocumentReference(firestore, Path.fromName(nativeData.path));
|
||||||
@ -47,11 +49,11 @@ export default class DocumentSnapshot {
|
|||||||
return this._ref;
|
return this._ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
data(): Object {
|
data(): Object | void {
|
||||||
return this._data;
|
return this._data;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(fieldPath: string): any {
|
get(fieldPath: string): any {
|
||||||
return this._data[fieldPath];
|
return this._data ? this._data[fieldPath] : undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* GeoPoint representation wrapper
|
* GeoPoint representation wrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class GeoPoint
|
* @class GeoPoint
|
||||||
*/
|
*/
|
||||||
export default class GeoPoint {
|
export default class GeoPoint {
|
||||||
@ -19,11 +19,11 @@ export default class GeoPoint {
|
|||||||
this._longitude = longitude;
|
this._longitude = longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
get latitude() {
|
get latitude(): number {
|
||||||
return this._latitude;
|
return this._latitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
get longitude() {
|
get longitude(): number {
|
||||||
return this._longitude;
|
return this._longitude;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Path representation wrapper
|
* Path representation wrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Path
|
* @class Path
|
||||||
*/
|
*/
|
||||||
export default class Path {
|
export default class Path {
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
* @flow
|
* @flow
|
||||||
* Query representation wrapper
|
* Query representation wrapper
|
||||||
*/
|
*/
|
||||||
import DocumentSnapshot from './DocumentSnapshot';
|
|
||||||
import Path from './Path';
|
|
||||||
import QuerySnapshot from './QuerySnapshot';
|
import QuerySnapshot from './QuerySnapshot';
|
||||||
import { buildNativeArray, buildTypeMap } from './utils/serialize';
|
import { buildNativeArray, buildTypeMap } from './utils/serialize';
|
||||||
import { firestoreAutoId, isFunction, isObject } from '../../utils';
|
import { firestoreAutoId, isFunction, isObject } from '../../utils';
|
||||||
|
|
||||||
|
import type DocumentSnapshot from './DocumentSnapshot';
|
||||||
|
import type Firestore from './';
|
||||||
|
import type Path from './Path';
|
||||||
|
|
||||||
const DIRECTIONS = {
|
const DIRECTIONS = {
|
||||||
ASC: 'ASCENDING',
|
ASC: 'ASCENDING',
|
||||||
asc: 'ASCENDING',
|
asc: 'ASCENDING',
|
||||||
@ -54,19 +56,25 @@ type Observer = {
|
|||||||
error?: (Object) => void,
|
error?: (Object) => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Query
|
* @class Query
|
||||||
*/
|
*/
|
||||||
export default class Query {
|
export default class Query {
|
||||||
_fieldFilters: FieldFilter[];
|
_fieldFilters: FieldFilter[];
|
||||||
_fieldOrders: FieldOrder[];
|
_fieldOrders: FieldOrder[];
|
||||||
_firestore: Object;
|
_firestore: Firestore;
|
||||||
_iid: number;
|
_iid: number;
|
||||||
_queryOptions: QueryOptions;
|
_queryOptions: QueryOptions;
|
||||||
_referencePath: Path;
|
_referencePath: Path;
|
||||||
|
|
||||||
constructor(firestore: Object, path: Path, fieldFilters?: FieldFilter[],
|
constructor(
|
||||||
fieldOrders?: FieldOrder[], queryOptions?: QueryOptions) {
|
firestore: Firestore,
|
||||||
|
path: Path,
|
||||||
|
fieldFilters?:
|
||||||
|
FieldFilter[],
|
||||||
|
fieldOrders?: FieldOrder[],
|
||||||
|
queryOptions?: QueryOptions,
|
||||||
|
) {
|
||||||
this._fieldFilters = fieldFilters || [];
|
this._fieldFilters = fieldFilters || [];
|
||||||
this._fieldOrders = fieldOrders || [];
|
this._fieldOrders = fieldOrders || [];
|
||||||
this._firestore = firestore;
|
this._firestore = firestore;
|
||||||
@ -78,24 +86,34 @@ export default class Query {
|
|||||||
return this._firestore;
|
return this._firestore;
|
||||||
}
|
}
|
||||||
|
|
||||||
endAt(...snapshotOrVarArgs: any): Query {
|
endAt(...snapshotOrVarArgs: any[]): Query {
|
||||||
const options = {
|
const options = {
|
||||||
...this._queryOptions,
|
...this._queryOptions,
|
||||||
endAt: this._buildOrderByOption(snapshotOrVarArgs),
|
endAt: this._buildOrderByOption(snapshotOrVarArgs),
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Query(this.firestore, this._referencePath, this._fieldFilters,
|
return new Query(
|
||||||
this._fieldOrders, options);
|
this.firestore,
|
||||||
|
this._referencePath,
|
||||||
|
this._fieldFilters,
|
||||||
|
this._fieldOrders,
|
||||||
|
options,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
endBefore(...snapshotOrVarArgs: any): Query {
|
endBefore(...snapshotOrVarArgs: any[]): Query {
|
||||||
const options = {
|
const options = {
|
||||||
...this._queryOptions,
|
...this._queryOptions,
|
||||||
endBefore: this._buildOrderByOption(snapshotOrVarArgs),
|
endBefore: this._buildOrderByOption(snapshotOrVarArgs),
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Query(this.firestore, this._referencePath, this._fieldFilters,
|
return new Query(
|
||||||
this._fieldOrders, options);
|
this.firestore,
|
||||||
|
this._referencePath,
|
||||||
|
this._fieldFilters,
|
||||||
|
this._fieldOrders,
|
||||||
|
options,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get(): Promise<QuerySnapshot> {
|
get(): Promise<QuerySnapshot> {
|
||||||
@ -117,14 +135,19 @@ export default class Query {
|
|||||||
...this._queryOptions,
|
...this._queryOptions,
|
||||||
limit,
|
limit,
|
||||||
};
|
};
|
||||||
return new Query(this.firestore, this._referencePath, this._fieldFilters,
|
return new Query(
|
||||||
this._fieldOrders, options);
|
this.firestore,
|
||||||
|
this._referencePath,
|
||||||
|
this._fieldFilters,
|
||||||
|
this._fieldOrders,
|
||||||
|
options,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSnapshot(
|
onSnapshot(
|
||||||
optionsOrObserverOrOnNext: QueryListenOptions | Observer | (DocumentSnapshot) => void,
|
optionsOrObserverOrOnNext: QueryListenOptions | Observer | (DocumentSnapshot) => void,
|
||||||
observerOrOnNextOrOnError?: Observer | (DocumentSnapshot) => void | (Object) => void,
|
observerOrOnNextOrOnError?: Observer | (DocumentSnapshot) => void | (Object) => void,
|
||||||
onError?: (Object) => void,
|
onError?: (Object) => void,
|
||||||
) {
|
) {
|
||||||
let observer = {};
|
let observer = {};
|
||||||
let queryListenOptions = {};
|
let queryListenOptions = {};
|
||||||
@ -199,12 +222,12 @@ export default class Query {
|
|||||||
// Add the native listener
|
// Add the native listener
|
||||||
this._firestore._native
|
this._firestore._native
|
||||||
.collectionOnSnapshot(
|
.collectionOnSnapshot(
|
||||||
this._referencePath.relativeName,
|
this._referencePath.relativeName,
|
||||||
this._fieldFilters,
|
this._fieldFilters,
|
||||||
this._fieldOrders,
|
this._fieldOrders,
|
||||||
this._queryOptions,
|
this._queryOptions,
|
||||||
listenerId,
|
listenerId,
|
||||||
queryListenOptions,
|
queryListenOptions,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Return an unsubscribe method
|
// Return an unsubscribe method
|
||||||
@ -226,28 +249,43 @@ export default class Query {
|
|||||||
fieldPath,
|
fieldPath,
|
||||||
};
|
};
|
||||||
const combinedOrders = this._fieldOrders.concat(newOrder);
|
const combinedOrders = this._fieldOrders.concat(newOrder);
|
||||||
return new Query(this.firestore, this._referencePath, this._fieldFilters,
|
return new Query(
|
||||||
combinedOrders, this._queryOptions);
|
this.firestore,
|
||||||
|
this._referencePath,
|
||||||
|
this._fieldFilters,
|
||||||
|
combinedOrders,
|
||||||
|
this._queryOptions,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
startAfter(...snapshotOrVarArgs: any): Query {
|
startAfter(...snapshotOrVarArgs: any[]): Query {
|
||||||
const options = {
|
const options = {
|
||||||
...this._queryOptions,
|
...this._queryOptions,
|
||||||
startAfter: this._buildOrderByOption(snapshotOrVarArgs),
|
startAfter: this._buildOrderByOption(snapshotOrVarArgs),
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Query(this.firestore, this._referencePath, this._fieldFilters,
|
return new Query(
|
||||||
this._fieldOrders, options);
|
this.firestore,
|
||||||
|
this._referencePath,
|
||||||
|
this._fieldFilters,
|
||||||
|
this._fieldOrders,
|
||||||
|
options,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
startAt(...snapshotOrVarArgs: any): Query {
|
startAt(...snapshotOrVarArgs: any[]): Query {
|
||||||
const options = {
|
const options = {
|
||||||
...this._queryOptions,
|
...this._queryOptions,
|
||||||
startAt: this._buildOrderByOption(snapshotOrVarArgs),
|
startAt: this._buildOrderByOption(snapshotOrVarArgs),
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Query(this.firestore, this._referencePath, this._fieldFilters,
|
return new Query(
|
||||||
this._fieldOrders, options);
|
this.firestore,
|
||||||
|
this._referencePath,
|
||||||
|
this._fieldFilters,
|
||||||
|
this._fieldOrders,
|
||||||
|
options,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
where(fieldPath: string, opStr: Operator, value: any): Query {
|
where(fieldPath: string, opStr: Operator, value: any): Query {
|
||||||
@ -261,8 +299,13 @@ export default class Query {
|
|||||||
value: nativeValue,
|
value: nativeValue,
|
||||||
};
|
};
|
||||||
const combinedFilters = this._fieldFilters.concat(newFilter);
|
const combinedFilters = this._fieldFilters.concat(newFilter);
|
||||||
return new Query(this.firestore, this._referencePath, combinedFilters,
|
return new Query(
|
||||||
this._fieldOrders, this._queryOptions);
|
this.firestore,
|
||||||
|
this._referencePath,
|
||||||
|
combinedFilters,
|
||||||
|
this._fieldOrders,
|
||||||
|
this._queryOptions,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,7 +333,7 @@ export default class Query {
|
|||||||
* Remove query snapshot listener
|
* Remove query snapshot listener
|
||||||
* @param listener
|
* @param listener
|
||||||
*/
|
*/
|
||||||
_offCollectionSnapshot(listenerId: number, listener: Function) {
|
_offCollectionSnapshot(listenerId: string, listener: Function) {
|
||||||
this._firestore.log.info('Removing onQuerySnapshot listener');
|
this._firestore.log.info('Removing onQuerySnapshot listener');
|
||||||
this._firestore.removeListener(this._firestore._getAppEventName(`onQuerySnapshot:${listenerId}`), listener);
|
this._firestore.removeListener(this._firestore._getAppEventName(`onQuerySnapshot:${listenerId}`), listener);
|
||||||
this._firestore.removeListener(this._firestore._getAppEventName(`onQuerySnapshotError:${listenerId}`), listener);
|
this._firestore.removeListener(this._firestore._getAppEventName(`onQuerySnapshotError:${listenerId}`), listener);
|
||||||
@ -300,7 +343,7 @@ export default class Query {
|
|||||||
this._fieldFilters,
|
this._fieldFilters,
|
||||||
this._fieldOrders,
|
this._fieldOrders,
|
||||||
this._queryOptions,
|
this._queryOptions,
|
||||||
listenerId
|
listenerId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
* @flow
|
* @flow
|
||||||
* QuerySnapshot representation wrapper
|
* QuerySnapshot representation wrapper
|
||||||
*/
|
*/
|
||||||
import DocumentChange from './DocumentChange';
|
import DocumentChange, { type DocumentChangeNativeData } from './DocumentChange';
|
||||||
import DocumentSnapshot from './DocumentSnapshot';
|
import DocumentSnapshot, { type DocumentSnapshotNativeData, type SnapshotMetadata } from './DocumentSnapshot';
|
||||||
import Query from './Query';
|
|
||||||
|
|
||||||
import type { DocumentChangeNativeData } from './DocumentChange';
|
import type Firestore from './';
|
||||||
import type { DocumentSnapshotNativeData, SnapshotMetadata } from './DocumentSnapshot';
|
import type Query from './Query';
|
||||||
|
|
||||||
type QuerySnapshotNativeData = {
|
type QuerySnapshotNativeData = {
|
||||||
changes: DocumentChangeNativeData[],
|
changes: DocumentChangeNativeData[],
|
||||||
@ -15,7 +14,7 @@ type QuerySnapshotNativeData = {
|
|||||||
metadata: SnapshotMetadata,
|
metadata: SnapshotMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class QuerySnapshot
|
* @class QuerySnapshot
|
||||||
*/
|
*/
|
||||||
export default class QuerySnapshot {
|
export default class QuerySnapshot {
|
||||||
@ -24,7 +23,7 @@ export default class QuerySnapshot {
|
|||||||
_metadata: SnapshotMetadata;
|
_metadata: SnapshotMetadata;
|
||||||
_query: Query;
|
_query: Query;
|
||||||
|
|
||||||
constructor(firestore: Object, query: Query, nativeData: QuerySnapshotNativeData) {
|
constructor(firestore: Firestore, query: Query, nativeData: QuerySnapshotNativeData) {
|
||||||
this._changes = nativeData.changes.map(change => new DocumentChange(firestore, change));
|
this._changes = nativeData.changes.map(change => new DocumentChange(firestore, change));
|
||||||
this._docs = nativeData.documents.map(doc => new DocumentSnapshot(firestore, doc));
|
this._docs = nativeData.documents.map(doc => new DocumentSnapshot(firestore, doc));
|
||||||
this._metadata = nativeData.metadata;
|
this._metadata = nativeData.metadata;
|
||||||
@ -43,14 +42,14 @@ export default class QuerySnapshot {
|
|||||||
return this._docs.length === 0;
|
return this._docs.length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get query(): Query {
|
|
||||||
return this._query;
|
|
||||||
}
|
|
||||||
|
|
||||||
get metadata(): SnapshotMetadata {
|
get metadata(): SnapshotMetadata {
|
||||||
return this._metadata;
|
return this._metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get query(): Query {
|
||||||
|
return this._query;
|
||||||
|
}
|
||||||
|
|
||||||
get size(): number {
|
get size(): number {
|
||||||
return this._docs.length;
|
return this._docs.length;
|
||||||
}
|
}
|
||||||
@ -59,8 +58,8 @@ export default class QuerySnapshot {
|
|||||||
// TODO: Validation
|
// TODO: Validation
|
||||||
// validate.isFunction('callback', callback);
|
// validate.isFunction('callback', callback);
|
||||||
|
|
||||||
for (const doc of this._docs) {
|
this._docs.forEach((doc) => {
|
||||||
callback(doc);
|
callback(doc);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
* @flow
|
* @flow
|
||||||
* WriteBatch representation wrapper
|
* WriteBatch representation wrapper
|
||||||
*/
|
*/
|
||||||
import DocumentReference from './DocumentReference';
|
|
||||||
import { buildNativeMap } from './utils/serialize';
|
import { buildNativeMap } from './utils/serialize';
|
||||||
import { isObject, isString } from '../../utils';
|
import { isObject, isString } from '../../utils';
|
||||||
|
|
||||||
import type { WriteOptions } from './DocumentReference';
|
import type DocumentReference, { WriteOptions } from './DocumentReference';
|
||||||
|
import type Firestore from './';
|
||||||
|
|
||||||
type DocumentWrite = {
|
type DocumentWrite = {
|
||||||
data?: Object,
|
data?: Object,
|
||||||
@ -15,14 +15,14 @@ type DocumentWrite = {
|
|||||||
type: 'DELETE' | 'SET' | 'UPDATE',
|
type: 'DELETE' | 'SET' | 'UPDATE',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class WriteBatch
|
* @class WriteBatch
|
||||||
*/
|
*/
|
||||||
export default class WriteBatch {
|
export default class WriteBatch {
|
||||||
_firestore: Object;
|
_firestore: Firestore;
|
||||||
_writes: DocumentWrite[];
|
_writes: DocumentWrite[];
|
||||||
|
|
||||||
constructor(firestore: Object) {
|
constructor(firestore: Firestore) {
|
||||||
this._firestore = firestore;
|
this._firestore = firestore;
|
||||||
this._writes = [];
|
this._writes = [];
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ export default class WriteBatch {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
update(docRef: DocumentReference, ...args: Object | string[]): WriteBatch {
|
update(docRef: DocumentReference, ...args: any[]): WriteBatch {
|
||||||
// TODO: Validation
|
// TODO: Validation
|
||||||
// validate.isDocumentReference('docRef', docRef);
|
// validate.isDocumentReference('docRef', docRef);
|
||||||
let data = {};
|
let data = {};
|
||||||
|
@ -5,13 +5,16 @@
|
|||||||
import ModuleBase from './../../utils/ModuleBase';
|
import ModuleBase from './../../utils/ModuleBase';
|
||||||
import CollectionReference from './CollectionReference';
|
import CollectionReference from './CollectionReference';
|
||||||
import DocumentReference from './DocumentReference';
|
import DocumentReference from './DocumentReference';
|
||||||
import DocumentSnapshot from './DocumentSnapshot';
|
|
||||||
import FieldValue from './FieldValue';
|
import FieldValue from './FieldValue';
|
||||||
import GeoPoint from './GeoPoint';
|
import GeoPoint from './GeoPoint';
|
||||||
import Path from './Path';
|
import Path from './Path';
|
||||||
import WriteBatch from './WriteBatch';
|
import WriteBatch from './WriteBatch';
|
||||||
import INTERNALS from './../../internals';
|
import INTERNALS from './../../internals';
|
||||||
|
|
||||||
|
import type DocumentSnapshot from './DocumentSnapshot';
|
||||||
|
import type FirebaseApp from '../../firebase-app';
|
||||||
|
import type QuerySnapshot from './QuerySnapshot';
|
||||||
|
|
||||||
type CollectionSyncEvent = {
|
type CollectionSyncEvent = {
|
||||||
appName: string,
|
appName: string,
|
||||||
querySnapshot?: QuerySnapshot,
|
querySnapshot?: QuerySnapshot,
|
||||||
@ -37,21 +40,21 @@ export default class Firestore extends ModuleBase {
|
|||||||
|
|
||||||
_referencePath: Path;
|
_referencePath: Path;
|
||||||
|
|
||||||
constructor(firebaseApp: Object, options: Object = {}) {
|
constructor(firebaseApp: FirebaseApp, options: Object = {}) {
|
||||||
super(firebaseApp, options, true);
|
super(firebaseApp, options, true);
|
||||||
this._referencePath = new Path([]);
|
this._referencePath = new Path([]);
|
||||||
|
|
||||||
this.addListener(
|
this.addListener(
|
||||||
// sub to internal native event - this fans out to
|
// sub to internal native event - this fans out to
|
||||||
// public event name: onCollectionSnapshot
|
// public event name: onCollectionSnapshot
|
||||||
this._getAppEventName('firestore_collection_sync_event'),
|
super._getAppEventName('firestore_collection_sync_event'),
|
||||||
this._onCollectionSyncEvent.bind(this),
|
this._onCollectionSyncEvent.bind(this),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addListener(
|
this.addListener(
|
||||||
// sub to internal native event - this fans out to
|
// sub to internal native event - this fans out to
|
||||||
// public event name: onDocumentSnapshot
|
// public event name: onDocumentSnapshot
|
||||||
this._getAppEventName('firestore_document_sync_event'),
|
super._getAppEventName('firestore_document_sync_event'),
|
||||||
this._onDocumentSyncEvent.bind(this),
|
this._onDocumentSyncEvent.bind(this),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -92,15 +95,15 @@ export default class Firestore extends ModuleBase {
|
|||||||
throw new Error('Persistence is enabled by default on the Firestore SDKs');
|
throw new Error('Persistence is enabled by default on the Firestore SDKs');
|
||||||
}
|
}
|
||||||
|
|
||||||
runTransaction(updateFunction): Promise<any> {
|
runTransaction(): Promise<any> {
|
||||||
throw new Error('firebase.firestore().runTransaction() coming soon');
|
throw new Error('firebase.firestore().runTransaction() coming soon');
|
||||||
}
|
}
|
||||||
|
|
||||||
setLogLevel(logLevel: 'debug' | 'error' | 'silent'): void {
|
setLogLevel(): void {
|
||||||
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(Firestore, 'setLogLevel'));
|
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(Firestore, 'setLogLevel'));
|
||||||
}
|
}
|
||||||
|
|
||||||
settings(settings: Object): void {
|
settings(): void {
|
||||||
throw new Error('firebase.firestore().settings() coming soon');
|
throw new Error('firebase.firestore().settings() coming soon');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,9 +118,9 @@ export default class Firestore extends ModuleBase {
|
|||||||
*/
|
*/
|
||||||
_onCollectionSyncEvent(event: CollectionSyncEvent) {
|
_onCollectionSyncEvent(event: CollectionSyncEvent) {
|
||||||
if (event.error) {
|
if (event.error) {
|
||||||
this.emit(this._getAppEventName(`onQuerySnapshotError:${event.listenerId}`), event.error);
|
this.emit(super._getAppEventName(`onQuerySnapshotError:${event.listenerId}`), event.error);
|
||||||
} else {
|
} else {
|
||||||
this.emit(this._getAppEventName(`onQuerySnapshot:${event.listenerId}`), event.querySnapshot);
|
this.emit(super._getAppEventName(`onQuerySnapshot:${event.listenerId}`), event.querySnapshot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,9 +131,9 @@ export default class Firestore extends ModuleBase {
|
|||||||
*/
|
*/
|
||||||
_onDocumentSyncEvent(event: DocumentSyncEvent) {
|
_onDocumentSyncEvent(event: DocumentSyncEvent) {
|
||||||
if (event.error) {
|
if (event.error) {
|
||||||
this.emit(this._getAppEventName(`onDocumentSnapshotError:${event.listenerId}`), event.error);
|
this.emit(super._getAppEventName(`onDocumentSnapshotError:${event.listenerId}`), event.error);
|
||||||
} else {
|
} else {
|
||||||
this.emit(this._getAppEventName(`onDocumentSnapshot:${event.listenerId}`), event.documentSnapshot);
|
this.emit(super._getAppEventName(`onDocumentSnapshot:${event.listenerId}`), event.documentSnapshot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
// @flow
|
/**
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
|
||||||
import DocumentReference from '../DocumentReference';
|
import DocumentReference from '../DocumentReference';
|
||||||
import { DELETE_FIELD_VALUE, SERVER_TIMESTAMP_FIELD_VALUE } from '../FieldValue';
|
import { DELETE_FIELD_VALUE, SERVER_TIMESTAMP_FIELD_VALUE } from '../FieldValue';
|
||||||
@ -6,8 +8,10 @@ import GeoPoint from '../GeoPoint';
|
|||||||
import Path from '../Path';
|
import Path from '../Path';
|
||||||
import { typeOf } from '../../../utils';
|
import { typeOf } from '../../../utils';
|
||||||
|
|
||||||
type TypeMap = {
|
import type Firestore from '../';
|
||||||
type: 'array' | 'boolean' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string',
|
|
||||||
|
export type TypeMap = {
|
||||||
|
type: 'array' | 'boolean' | 'date' | 'fieldvalue' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string',
|
||||||
value: any,
|
value: any,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,65 +21,86 @@ type TypeMap = {
|
|||||||
* for transmission to the native side
|
* for transmission to the native side
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const buildNativeMap = (data: Object): Object => {
|
export const buildNativeMap = (data: Object): { [string]: TypeMap } => {
|
||||||
const nativeData = {};
|
const nativeData = {};
|
||||||
if (data) {
|
if (data) {
|
||||||
Object.keys(data).forEach((key) => {
|
Object.keys(data).forEach((key) => {
|
||||||
nativeData[key] = buildTypeMap(data[key]);
|
const typeMap = buildTypeMap(data[key]);
|
||||||
|
if (typeMap) {
|
||||||
|
nativeData[key] = typeMap;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return nativeData;
|
return nativeData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const buildNativeArray = (array: Object[]): any[] => {
|
export const buildNativeArray = (array: Object[]): TypeMap[] => {
|
||||||
const nativeArray = [];
|
const nativeArray = [];
|
||||||
if (array) {
|
if (array) {
|
||||||
array.forEach((value) => {
|
array.forEach((value) => {
|
||||||
nativeArray.push(buildTypeMap(value));
|
const typeMap = buildTypeMap(value);
|
||||||
|
if (typeMap) {
|
||||||
|
nativeArray.push(typeMap);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return nativeArray;
|
return nativeArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const buildTypeMap = (value: any): any => {
|
export const buildTypeMap = (value: any): TypeMap | null => {
|
||||||
const typeMap = {};
|
|
||||||
const type = typeOf(value);
|
const type = typeOf(value);
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
typeMap.type = 'null';
|
return {
|
||||||
typeMap.value = null;
|
type: 'null',
|
||||||
|
value: null,
|
||||||
|
};
|
||||||
} else if (value === DELETE_FIELD_VALUE) {
|
} else if (value === DELETE_FIELD_VALUE) {
|
||||||
typeMap.type = 'fieldvalue';
|
return {
|
||||||
typeMap.value = 'delete';
|
type: 'fieldvalue',
|
||||||
|
value: 'delete',
|
||||||
|
};
|
||||||
} else if (value === SERVER_TIMESTAMP_FIELD_VALUE) {
|
} else if (value === SERVER_TIMESTAMP_FIELD_VALUE) {
|
||||||
typeMap.type = 'fieldvalue';
|
return {
|
||||||
typeMap.value = 'timestamp';
|
type: 'fieldvalue',
|
||||||
|
value: 'timestamp',
|
||||||
|
};
|
||||||
} else if (type === 'boolean' || type === 'number' || type === 'string') {
|
} else if (type === 'boolean' || type === 'number' || type === 'string') {
|
||||||
typeMap.type = type;
|
return {
|
||||||
typeMap.value = value;
|
type,
|
||||||
|
value,
|
||||||
|
};
|
||||||
} else if (type === 'array') {
|
} else if (type === 'array') {
|
||||||
typeMap.type = type;
|
return {
|
||||||
typeMap.value = buildNativeArray(value);
|
type,
|
||||||
|
value: buildNativeArray(value),
|
||||||
|
};
|
||||||
} else if (type === 'object') {
|
} else if (type === 'object') {
|
||||||
if (value instanceof DocumentReference) {
|
if (value instanceof DocumentReference) {
|
||||||
typeMap.type = 'reference';
|
return {
|
||||||
typeMap.value = value.path;
|
type: 'reference',
|
||||||
|
value: value.path,
|
||||||
|
};
|
||||||
} else if (value instanceof GeoPoint) {
|
} else if (value instanceof GeoPoint) {
|
||||||
typeMap.type = 'geopoint';
|
return {
|
||||||
typeMap.value = {
|
type: 'geopoint',
|
||||||
latitude: value.latitude,
|
value: {
|
||||||
longitude: value.longitude,
|
latitude: value.latitude,
|
||||||
|
longitude: value.longitude,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
} else if (value instanceof Date) {
|
} else if (value instanceof Date) {
|
||||||
typeMap.type = 'date';
|
return {
|
||||||
typeMap.value = value.getTime();
|
type: 'date',
|
||||||
} else {
|
value: value.getTime(),
|
||||||
typeMap.type = 'object';
|
};
|
||||||
typeMap.value = buildNativeMap(value);
|
|
||||||
}
|
}
|
||||||
} else {
|
return {
|
||||||
console.warn(`Unknown data type received ${type}`);
|
type: 'object',
|
||||||
|
value: buildNativeMap(value),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return typeMap;
|
console.warn(`Unknown data type received ${type}`);
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,7 +108,7 @@ export const buildTypeMap = (value: any): any => {
|
|||||||
* side and converts to the correct Firestore JS types
|
* side and converts to the correct Firestore JS types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const parseNativeMap = (firestore: Object, nativeData: Object): Object => {
|
export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: TypeMap }): Object | void => {
|
||||||
let data;
|
let data;
|
||||||
if (nativeData) {
|
if (nativeData) {
|
||||||
data = {};
|
data = {};
|
||||||
@ -94,7 +119,7 @@ export const parseNativeMap = (firestore: Object, nativeData: Object): Object =>
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseNativeArray = (firestore: Object, nativeArray: Object[]): any[] => {
|
const parseNativeArray = (firestore: Firestore, nativeArray: TypeMap[]): any[] => {
|
||||||
const array = [];
|
const array = [];
|
||||||
if (nativeArray) {
|
if (nativeArray) {
|
||||||
nativeArray.forEach((typeMap) => {
|
nativeArray.forEach((typeMap) => {
|
||||||
@ -104,7 +129,7 @@ const parseNativeArray = (firestore: Object, nativeArray: Object[]): any[] => {
|
|||||||
return array;
|
return array;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseTypeMap = (firestore: Object, typeMap: TypeMap): any => {
|
const parseTypeMap = (firestore: Firestore, typeMap: TypeMap): any => {
|
||||||
const { type, value } = typeMap;
|
const { type, value } = typeMap;
|
||||||
if (type === 'null') {
|
if (type === 'null') {
|
||||||
return null;
|
return null;
|
||||||
|
@ -6,9 +6,10 @@ import { NativeModules } from 'react-native';
|
|||||||
import Log from '../utils/log';
|
import Log from '../utils/log';
|
||||||
import INTERNALS from './../internals';
|
import INTERNALS from './../internals';
|
||||||
import FirebaseCore from './../firebase';
|
import FirebaseCore from './../firebase';
|
||||||
import FirebaseApp from '../firebase-app';
|
|
||||||
import { nativeWithApp } from './../utils';
|
import { nativeWithApp } from './../utils';
|
||||||
|
|
||||||
|
import type FirebaseApp from '../firebase-app';
|
||||||
|
|
||||||
const logs = {};
|
const logs = {};
|
||||||
|
|
||||||
// Firebase Native SDKs that support multiple app instances
|
// Firebase Native SDKs that support multiple app instances
|
||||||
@ -50,7 +51,7 @@ export default class ModuleBase {
|
|||||||
_options: Object;
|
_options: Object;
|
||||||
_appName: string;
|
_appName: string;
|
||||||
_namespace: string;
|
_namespace: string;
|
||||||
_firebaseApp: Object;
|
_firebaseApp: FirebaseApp;
|
||||||
_eventEmitter: Object;
|
_eventEmitter: Object;
|
||||||
static _NAMESPACE: string;
|
static _NAMESPACE: string;
|
||||||
static _NATIVE_MODULE: string;
|
static _NATIVE_MODULE: string;
|
||||||
@ -61,7 +62,7 @@ export default class ModuleBase {
|
|||||||
* @param options
|
* @param options
|
||||||
* @param withEventEmitter
|
* @param withEventEmitter
|
||||||
*/
|
*/
|
||||||
constructor(firebaseApp: Object, options: Object, withEventEmitter: boolean = false) {
|
constructor(firebaseApp: FirebaseApp, options: Object, withEventEmitter: boolean = false) {
|
||||||
this._module = this.constructor._NATIVE_MODULE.replace('RNFirebase', '');
|
this._module = this.constructor._NATIVE_MODULE.replace('RNFirebase', '');
|
||||||
this._firebaseApp = firebaseApp;
|
this._firebaseApp = firebaseApp;
|
||||||
this._appName = firebaseApp._name;
|
this._appName = firebaseApp._name;
|
||||||
@ -73,12 +74,7 @@ export default class ModuleBase {
|
|||||||
const nativeModule = NativeModules[this.constructor._NATIVE_MODULE];
|
const nativeModule = NativeModules[this.constructor._NATIVE_MODULE];
|
||||||
|
|
||||||
if (!nativeModule) {
|
if (!nativeModule) {
|
||||||
throw new Error(
|
throw new Error(INTERNALS.STRINGS.ERROR_MISSING_MODULE(this.constructor._NAMESPACE, this.constructor._NATIVE_MODULE));
|
||||||
INTERNALS.STRINGS.ERROR_MISSING_MODULE(
|
|
||||||
this.constructor._NAMESPACE,
|
|
||||||
this.constructor._NATIVE_MODULE,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by the modules that extend ModuleBase
|
// used by the modules that extend ModuleBase
|
||||||
@ -100,7 +96,7 @@ export default class ModuleBase {
|
|||||||
* @param moduleName
|
* @param moduleName
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setupEventEmitter(nativeModule, moduleName) {
|
_setupEventEmitter(nativeModule: Object, moduleName: string) {
|
||||||
this._eventEmitter = FirebaseCore._getOrSetNativeEmitter(`${this._appName}-${this._module}`, nativeModule);
|
this._eventEmitter = FirebaseCore._getOrSetNativeEmitter(`${this._appName}-${this._module}`, nativeModule);
|
||||||
const events = NATIVE_MODULE_EVENTS[moduleName];
|
const events = NATIVE_MODULE_EVENTS[moduleName];
|
||||||
|
|
||||||
@ -117,7 +113,7 @@ export default class ModuleBase {
|
|||||||
* @return {string}
|
* @return {string}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_getAppEventName(eventName) {
|
_getAppEventName(eventName: string) {
|
||||||
return `${this._appName}-${eventName}`;
|
return `${this._appName}-${eventName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,9 +127,7 @@ export default class ModuleBase {
|
|||||||
|
|
||||||
get log(): Log {
|
get log(): Log {
|
||||||
if (logs[this._namespace]) return logs[this._namespace];
|
if (logs[this._namespace]) return logs[this._namespace];
|
||||||
return logs[this._namespace] = Log.createLogger(
|
return logs[this._namespace] = Log.createLogger(`🔥 ${this._namespace.toUpperCase()}`);
|
||||||
`🔥 ${this._namespace.toUpperCase()}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
import Log from './log';
|
||||||
|
|
||||||
|
import type Database from '../modules/database';
|
||||||
|
import type Storage from '../modules/storage';
|
||||||
|
|
||||||
export default class ReferenceBase {
|
export default class ReferenceBase {
|
||||||
constructor(path: string, module) {
|
_module: Database | Storage;
|
||||||
|
path: string;
|
||||||
|
|
||||||
|
constructor(path: string, module: Database | Storage) {
|
||||||
this._module = module;
|
this._module = module;
|
||||||
this.path = path || '/';
|
this.path = path || '/';
|
||||||
}
|
}
|
||||||
@ -17,7 +25,7 @@ export default class ReferenceBase {
|
|||||||
return this.path === '/' ? null : this.path.substring(this.path.lastIndexOf('/') + 1);
|
return this.path === '/' ? null : this.path.substring(this.path.lastIndexOf('/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
get log() {
|
get log(): Log {
|
||||||
return this._module.log;
|
return this._module.log;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
import { NativeEventEmitter } from 'react-native';
|
import { NativeEventEmitter } from 'react-native';
|
||||||
|
|
||||||
import INTERNALS from './../internals';
|
import INTERNALS from './../internals';
|
||||||
@ -6,13 +9,13 @@ import DatabaseReference from './../modules/database/reference';
|
|||||||
import { isString, nativeToJSError } from './../utils';
|
import { isString, nativeToJSError } from './../utils';
|
||||||
|
|
||||||
type Registration = {
|
type Registration = {
|
||||||
key: String,
|
key: string,
|
||||||
path: String,
|
path: string,
|
||||||
once?: Boolean,
|
once?: boolean,
|
||||||
appName: String,
|
appName: string,
|
||||||
eventType: String,
|
eventType: string,
|
||||||
listener: Function,
|
listener: Function,
|
||||||
eventRegistrationKey: String,
|
eventRegistrationKey: string,
|
||||||
ref: DatabaseReference,
|
ref: DatabaseReference,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +24,12 @@ type Registration = {
|
|||||||
* subscriptions and keep the listeners in sync in js vs native.
|
* subscriptions and keep the listeners in sync in js vs native.
|
||||||
*/
|
*/
|
||||||
export default class SyncTree {
|
export default class SyncTree {
|
||||||
constructor(databaseNative) {
|
_databaseNative: Object;
|
||||||
|
_nativeEmitter: NativeEventEmitter;
|
||||||
|
_reverseLookup: { [string]: Registration };
|
||||||
|
_tree: { [string]: { [string]: Array }};
|
||||||
|
|
||||||
|
constructor(databaseNative: Object) {
|
||||||
this._tree = {};
|
this._tree = {};
|
||||||
this._reverseLookup = {};
|
this._reverseLookup = {};
|
||||||
this._databaseNative = databaseNative;
|
this._databaseNative = databaseNative;
|
||||||
@ -110,7 +118,7 @@ export default class SyncTree {
|
|||||||
* @param registration
|
* @param registration
|
||||||
* @return {null}
|
* @return {null}
|
||||||
*/
|
*/
|
||||||
getRegistration(registration): Registration | null {
|
getRegistration(registration: string): Registration | null {
|
||||||
return this._reverseLookup[registration] ? Object.assign({}, this._reverseLookup[registration]) : null;
|
return this._reverseLookup[registration] ? Object.assign({}, this._reverseLookup[registration]) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +128,7 @@ export default class SyncTree {
|
|||||||
* @param registrations
|
* @param registrations
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
removeListenersForRegistrations(registrations) {
|
removeListenersForRegistrations(registrations: string | string[]) {
|
||||||
if (isString(registrations)) {
|
if (isString(registrations)) {
|
||||||
this.removeRegistration(registrations);
|
this.removeRegistration(registrations);
|
||||||
INTERNALS.SharedEventEmitter.removeAllListeners(registrations);
|
INTERNALS.SharedEventEmitter.removeAllListeners(registrations);
|
||||||
@ -143,7 +151,7 @@ export default class SyncTree {
|
|||||||
* @param registrations
|
* @param registrations
|
||||||
* @return {Array} array of registrations removed
|
* @return {Array} array of registrations removed
|
||||||
*/
|
*/
|
||||||
removeListenerRegistrations(listener, registrations) {
|
removeListenerRegistrations(listener, registrations: string[]) {
|
||||||
if (!Array.isArray(registrations)) return [];
|
if (!Array.isArray(registrations)) return [];
|
||||||
const removed = [];
|
const removed = [];
|
||||||
|
|
||||||
@ -173,7 +181,7 @@ export default class SyncTree {
|
|||||||
* @param path
|
* @param path
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
getRegistrationsByPath(path): Array {
|
getRegistrationsByPath(path: string): Array {
|
||||||
const out = [];
|
const out = [];
|
||||||
const eventKeys = Object.keys(this._tree[path] || {});
|
const eventKeys = Object.keys(this._tree[path] || {});
|
||||||
|
|
||||||
@ -191,7 +199,7 @@ export default class SyncTree {
|
|||||||
* @param eventType
|
* @param eventType
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
getRegistrationsByPathEvent(path, eventType): Array {
|
getRegistrationsByPathEvent(path: string, eventType: string): Array {
|
||||||
if (!this._tree[path]) return [];
|
if (!this._tree[path]) return [];
|
||||||
if (!this._tree[path][eventType]) return [];
|
if (!this._tree[path][eventType]) return [];
|
||||||
|
|
||||||
@ -228,8 +236,13 @@ export default class SyncTree {
|
|||||||
* @param listener
|
* @param listener
|
||||||
* @return {String}
|
* @return {String}
|
||||||
*/
|
*/
|
||||||
addRegistration(parameters: Registration, listener): String {
|
addRegistration(parameters: Registration, listener: Function): string {
|
||||||
const { path, eventType, eventRegistrationKey, once } = parameters;
|
const {
|
||||||
|
path,
|
||||||
|
eventType,
|
||||||
|
eventRegistrationKey,
|
||||||
|
once,
|
||||||
|
} = parameters;
|
||||||
|
|
||||||
if (!this._tree[path]) this._tree[path] = {};
|
if (!this._tree[path]) this._tree[path] = {};
|
||||||
if (!this._tree[path][eventType]) this._tree[path][eventType] = {};
|
if (!this._tree[path][eventType]) this._tree[path][eventType] = {};
|
||||||
@ -256,7 +269,7 @@ export default class SyncTree {
|
|||||||
* @param registration
|
* @param registration
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
removeRegistration(registration: String): Boolean {
|
removeRegistration(registration: string): boolean {
|
||||||
if (!this._reverseLookup[registration]) return false;
|
if (!this._reverseLookup[registration]) return false;
|
||||||
const { path, eventType, once } = this._reverseLookup[registration];
|
const { path, eventType, once } = this._reverseLookup[registration];
|
||||||
|
|
||||||
@ -298,4 +311,3 @@ export default class SyncTree {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,18 +6,10 @@ import { Platform } from 'react-native';
|
|||||||
// modeled after base64 web-safe chars, but ordered by ASCII
|
// modeled after base64 web-safe chars, but ordered by ASCII
|
||||||
const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
|
const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
|
||||||
const AUTO_ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
const AUTO_ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
const hasOwnProperty = Object.hasOwnProperty;
|
const { hasOwnProperty } = Object;
|
||||||
|
|
||||||
// const DEFAULT_CHUNK_SIZE = 50;
|
// const DEFAULT_CHUNK_SIZE = 50;
|
||||||
|
|
||||||
// Source: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical
|
|
||||||
const REGEXP_FIELD_NAME = new RegExp(
|
|
||||||
`^(?:\\.?((?:(?:[A-Za-z_][A-Za-z_0-9]*)|(?:[A-Za-z_][A-Za-z_0-9]*))+))$`
|
|
||||||
);
|
|
||||||
const REGEXP_FIELD_PATH = new RegExp(
|
|
||||||
`^((?:(?:[A-Za-z_][A-Za-z_0-9]*)|(?:[A-Za-z_][A-Za-z_0-9]*))+)(?:\\.((?:(?:[A-Za-z_][A-Za-z_0-9]*)|(?:[A-Za-z_][A-Za-z_0-9]*))+))*$`
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deep get a value from an object.
|
* Deep get a value from an object.
|
||||||
* @website https://github.com/Salakar/deeps
|
* @website https://github.com/Salakar/deeps
|
||||||
@ -26,9 +18,7 @@ const REGEXP_FIELD_PATH = new RegExp(
|
|||||||
* @param joiner
|
* @param joiner
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export function deepGet(object: Object,
|
export function deepGet(object: Object, path: string, joiner?: string = '/'): any {
|
||||||
path: string,
|
|
||||||
joiner?: string = '/'): any {
|
|
||||||
const keys = path.split(joiner);
|
const keys = path.split(joiner);
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@ -52,9 +42,7 @@ export function deepGet(object: Object,
|
|||||||
* @param joiner
|
* @param joiner
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export function deepExists(object: Object,
|
export function deepExists(object: Object, path: string, joiner?: string = '/'): boolean {
|
||||||
path: string,
|
|
||||||
joiner?: string = '/'): boolean {
|
|
||||||
const keys = path.split(joiner);
|
const keys = path.split(joiner);
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@ -98,7 +86,7 @@ export function areObjectKeysContainedInOther(obj1 : Object, obj2: Object): bool
|
|||||||
* @param arr2
|
* @param arr2
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isArrayContainedInOther(arr1: Array, arr2: Array): boolean {
|
export function isArrayContainedInOther(arr1: Array<*>, arr2: Array<*>): boolean {
|
||||||
if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
|
if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -112,8 +100,8 @@ export function isArrayContainedInOther(arr1: Array, arr2: Array): boolean {
|
|||||||
* @param item
|
* @param item
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isObject(item: any): boolean {
|
export function isObject(item: mixed): boolean %checks {
|
||||||
return (item && typeof item === 'object' && !Array.isArray(item) && item !== null);
|
return item ? (typeof item === 'object' && !Array.isArray(item) && item !== null) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,8 +109,8 @@ export function isObject(item: any): boolean {
|
|||||||
* @param item
|
* @param item
|
||||||
* @returns {*|boolean}
|
* @returns {*|boolean}
|
||||||
*/
|
*/
|
||||||
export function isFunction(item?: any): boolean {
|
export function isFunction(item?: mixed): boolean %checks {
|
||||||
return Boolean(item && typeof item === 'function');
|
return item ? typeof item === 'function' : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,20 +118,10 @@ export function isFunction(item?: any): boolean {
|
|||||||
* @param value
|
* @param value
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
export function isString(value: any): boolean {
|
export function isString(value: mixed): boolean %checks {
|
||||||
return typeof value === 'string';
|
return typeof value === 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Firestore field name/path validator.
|
|
||||||
* @param field
|
|
||||||
* @param paths
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
export function isValidFirestoreField(field, paths) {
|
|
||||||
return (paths ? REGEXP_FIELD_PATH : REGEXP_FIELD_NAME).test(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
// platform checks
|
// platform checks
|
||||||
export const isIOS = Platform.OS === 'ios';
|
export const isIOS = Platform.OS === 'ios';
|
||||||
export const isAndroid = Platform.OS === 'android';
|
export const isAndroid = Platform.OS === 'android';
|
||||||
@ -167,7 +145,7 @@ export function tryJSONParse(string: string | null): any {
|
|||||||
* @param data
|
* @param data
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export function tryJSONStringify(data: any): string | null {
|
export function tryJSONStringify(data: mixed): string | null {
|
||||||
try {
|
try {
|
||||||
return JSON.stringify(data);
|
return JSON.stringify(data);
|
||||||
} catch (jsonError) {
|
} catch (jsonError) {
|
||||||
|
3070
package-lock.json
generated
3070
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@ -75,13 +75,13 @@
|
|||||||
"babel-preset-react-native": "^1.9.0",
|
"babel-preset-react-native": "^1.9.0",
|
||||||
"debug": "^2.2.0",
|
"debug": "^2.2.0",
|
||||||
"enzyme": "^2.4.1",
|
"enzyme": "^2.4.1",
|
||||||
"eslint": "^3.8.1",
|
"eslint": "^4.11.0",
|
||||||
"eslint-config-airbnb": "^12.0.0",
|
"eslint-config-airbnb": "^16.1.0",
|
||||||
"eslint-plugin-flowtype": "^2.20.0",
|
"eslint-plugin-flowtype": "^2.39.1",
|
||||||
"eslint-plugin-import": "^2.0.1",
|
"eslint-plugin-import": "^2.8.0",
|
||||||
"eslint-plugin-jsx-a11y": "^2.2.3",
|
"eslint-plugin-jsx-a11y": "^6.0.2",
|
||||||
"eslint-plugin-react": "^6.4.1",
|
"eslint-plugin-react": "^7.4.0",
|
||||||
"flow-bin": "^0.55.0",
|
"flow-bin": "^0.56.0",
|
||||||
"react": "^16.0.0",
|
"react": "^16.0.0",
|
||||||
"react-dom": "^16.0.0",
|
"react-dom": "^16.0.0",
|
||||||
"react-native": "^0.48.0",
|
"react-native": "^0.48.0",
|
||||||
|
@ -208,7 +208,7 @@ SPEC CHECKSUMS:
|
|||||||
nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3
|
nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3
|
||||||
Protobuf: 03eef2ee0b674770735cf79d9c4d3659cf6908e8
|
Protobuf: 03eef2ee0b674770735cf79d9c4d3659cf6908e8
|
||||||
React: cf892fb84b7d06bf5fea7f328e554c6dcabe85ee
|
React: cf892fb84b7d06bf5fea7f328e554c6dcabe85ee
|
||||||
RNFirebase: a76befd482c5e84df7f69893358abda498ee9f76
|
RNFirebase: 1b8adf4dfe740fbc4a69a147715c2edfd041eb92
|
||||||
yoga: 3abf02d6d9aeeb139b4c930eb1367feae690a35a
|
yoga: 3abf02d6d9aeeb139b4c930eb1367feae690a35a
|
||||||
|
|
||||||
PODFILE CHECKSUM: b5674be55653f5dda937c8b794d0479900643d45
|
PODFILE CHECKSUM: b5674be55653f5dda937c8b794d0479900643d45
|
||||||
|
@ -1033,7 +1033,7 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
6AE1012F46FF8A4D1D818A12 /* [CP] Copy Pods Resources */ = {
|
6AE1012F46FF8A4D1D818A12 /* [CP] Copy Pods Resources */ = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user