2
0
mirror of synced 2025-02-02 17:43:27 +00:00

merge master

This commit is contained in:
Salakar 2018-03-01 16:32:44 +00:00
commit a21fc755a1
47 changed files with 330 additions and 239 deletions

View File

@ -55,7 +55,6 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(si
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
suppress_comment=\\(.\\|\n\\)*\\$FlowBug.*
unsafe.enable_getters_and_setters=true unsafe.enable_getters_and_setters=true

View File

@ -7,10 +7,12 @@ First, thank you for considering contributing to react-native-firebase! It's peo
We welcome any type of contribution, not only code. You can help with We welcome any type of contribution, not only code. You can help with
* **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open) * **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open)
* **Docs**: improve reference coverage, add more examples, fix any typos or anything else you can spot. At the top of every page on our docs site you can click the `Edit` pencil to go to that pages markdown file, or view the [Docs Repo](https://github.com/invertase/react-native-firebase-docs) directly
* **Marketing**: writing blog posts, howto's, printing stickers, ... * **Marketing**: writing blog posts, howto's, printing stickers, ...
* **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ... * **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ...
* **Code**: take a look at the [open issues](issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. It helps us triage them. * **Code**: take a look at the [open issues](issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. It helps us triage them.
* **Money**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/react-native-firebase). * **Money**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/react-native-firebase).
* **Premium Starter Kits**: purchasing one of our starter kits helps us continue to develop the library and support its ever growing community (and you get something too!). [View Kits](http://invertase.link/get-started-premium)
## Your First Contribution ## Your First Contribution
@ -32,8 +34,7 @@ Anyone can file an expense. If the expense makes sense for the development of th
## Questions ## Questions
If you have any questions, create an [issue](issue) (protip: do a quick search first to see if someone else didn't ask the same question before!). For questions and support please use our [Discord chat](https://discord.gg/C9aK28N) or [Stack Overflow](https://stackoverflow.com/questions/tagged/react-native-firebase). The issue list of this repo is **exclusively** for bug reports.
You can also reach us at oss@invertase.io
## Credits ## Credits

View File

@ -11,7 +11,7 @@
<a href="/LICENSE"><img src="https://img.shields.io/npm/l/react-native-firebase.svg?style=flat-square" alt="License"></a> <a href="/LICENSE"><img src="https://img.shields.io/npm/l/react-native-firebase.svg?style=flat-square" alt="License"></a>
<a href="#backers"><img src="https://opencollective.com/react-native-firebase/backers/badge.svg" alt="Backers on Open Collective"></a> <a href="#backers"><img src="https://opencollective.com/react-native-firebase/backers/badge.svg" alt="Backers on Open Collective"></a>
<a href="#sponsors"><img src="https://opencollective.com/react-native-firebase/sponsors/badge.svg" alt="Sponsors on Open Collective"></a> <a href="#sponsors"><img src="https://opencollective.com/react-native-firebase/sponsors/badge.svg" alt="Sponsors on Open Collective"></a>
<a href="https://discord.gg/C9aK28N"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg?style=flat-square" alt="Chat"></a> <a href="https://discord.gg/C9aK28N"><img src="https://img.shields.io/discord/295953187817521152.svg?logo=discord&style=flat-square&colorA=7289da&label=discord" alt="Chat"></a>
<a href="https://twitter.com/rnfirebase"><img src="https://img.shields.io/twitter/follow/rnfirebase.svg?style=social&label=Follow" alt="Follow on Twitter"></a> <a href="https://twitter.com/rnfirebase"><img src="https://img.shields.io/twitter/follow/rnfirebase.svg?style=social&label=Follow" alt="Follow on Twitter"></a>
</p> </p>

View File

@ -49,7 +49,6 @@ RCT_EXPORT_METHOD(fetch:
(RCTPromiseRejectBlock) reject) { (RCTPromiseRejectBlock) reject) {
[[FIRRemoteConfig remoteConfig] fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *__nullable error) { [[FIRRemoteConfig remoteConfig] fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *__nullable error) {
if (error) { if (error) {
RCTLogError(@"\nError: %@", RCTJSErrorFromNSError(error));
reject(convertFIRRemoteConfigFetchStatusToNSString(status), error.localizedDescription, error); reject(convertFIRRemoteConfigFetchStatusToNSString(status), error.localizedDescription, error);
} else { } else {
resolve(convertFIRRemoteConfigFetchStatusToNSString(status)); resolve(convertFIRRemoteConfigFetchStatusToNSString(status));
@ -64,7 +63,6 @@ RCT_EXPORT_METHOD(fetchWithExpirationDuration:
rejecter:(RCTPromiseRejectBlock)reject) { rejecter:(RCTPromiseRejectBlock)reject) {
[[FIRRemoteConfig remoteConfig] fetchWithExpirationDuration:expirationDuration.doubleValue completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *__nullable error) { [[FIRRemoteConfig remoteConfig] fetchWithExpirationDuration:expirationDuration.doubleValue completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *__nullable error) {
if (error) { if (error) {
RCTLogError(@"\nError: %@", RCTJSErrorFromNSError(error));
reject(convertFIRRemoteConfigFetchStatusToNSString(status), error.localizedDescription, error); reject(convertFIRRemoteConfigFetchStatusToNSString(status), error.localizedDescription, error);
} else { } else {
resolve(convertFIRRemoteConfigFetchStatusToNSString(status)); resolve(convertFIRRemoteConfigFetchStatusToNSString(status));

View File

@ -3,6 +3,64 @@
*/ */
import firebase from './modules/core/firebase'; import firebase from './modules/core/firebase';
export default firebase;
/*
* Export App types
*/
export type { default as App } from './modules/core/app';
/*
* Export Auth types
*/
export type {
ActionCodeInfo,
ActionCodeSettings,
AdditionalUserInfo,
AuthCredential,
UserCredential,
UserInfo,
UserMetadata,
} from './modules/auth/types';
export type {
default as ConfirmationResult,
} from './modules/auth/ConfirmationResult';
export type { default as User } from './modules/auth/User'; export type { default as User } from './modules/auth/User';
export default firebase; /*
* Export Database types
*/
export type { default as DataSnapshot } from './modules/database/DataSnapshot';
export type { default as OnDisconnect } from './modules/database/OnDisconnect';
export type { default as Reference } from './modules/database/Reference';
export type { default as DataQuery } from './modules/database/Query';
/*
* Export Firestore types
*/
export type {
DocumentListenOptions,
QueryListenOptions,
SetOptions,
SnapshotMetadata,
} from './modules/firestore/types';
export type {
default as CollectionReference,
} from './modules/firestore/CollectionReference';
export type {
default as DocumentChange,
} from './modules/firestore/DocumentChange';
export type {
default as DocumentReference,
} from './modules/firestore/DocumentReference';
export type {
default as DocumentSnapshot,
} from './modules/firestore/DocumentSnapshot';
export type { default as FieldPath } from './modules/firestore/FieldPath';
export type { default as FieldValue } from './modules/firestore/FieldValue';
export type { default as GeoPoint } from './modules/firestore/GeoPoint';
export type { default as Query } from './modules/firestore/Query';
export type {
default as QuerySnapshot,
} from './modules/firestore/QuerySnapshot';
export type { default as WriteBatch } from './modules/firestore/WriteBatch';

View File

@ -19,7 +19,7 @@ import EventTypes, {
RewardedVideoEventTypes, RewardedVideoEventTypes,
} from './EventTypes'; } from './EventTypes';
import type App from '../core/firebase-app'; import type App from '../core/app';
type NativeEvent = { type NativeEvent = {
adUnit: string, adUnit: string,

View File

@ -5,7 +5,7 @@
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
const AlphaNumericUnderscore = /^[a-zA-Z0-9_]+$/; const AlphaNumericUnderscore = /^[a-zA-Z0-9_]+$/;

View File

@ -109,7 +109,7 @@ export default class PhoneAuthListener {
const type = events[i]; const type = events[i];
SharedEventEmitter.once( SharedEventEmitter.once(
this._internalEvents[type], this._internalEvents[type],
// $FlowBug: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 // $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323
this[`_${type}Handler`].bind(this) this[`_${type}Handler`].bind(this)
); );
} }

View File

@ -11,18 +11,10 @@ import type {
AuthCredential, AuthCredential,
NativeUser, NativeUser,
UserCredential, UserCredential,
UserInfo,
UserMetadata, UserMetadata,
} from './types'; } from './types';
type UserInfo = {
displayName?: string,
email?: string,
phoneNumber?: string,
photoURL?: string,
providerId: string,
uid: string,
};
type UpdateProfile = { type UpdateProfile = {
displayName?: string, displayName?: string,
photoURL?: string, photoURL?: string,

View File

@ -22,26 +22,19 @@ import FacebookAuthProvider from './providers/FacebookAuthProvider';
import PhoneAuthListener from './PhoneAuthListener'; import PhoneAuthListener from './PhoneAuthListener';
import type { import type {
ActionCodeInfo,
ActionCodeSettings, ActionCodeSettings,
AuthCredential, AuthCredential,
NativeUser, NativeUser,
NativeUserCredential, NativeUserCredential,
UserCredential, UserCredential,
} from './types'; } from './types';
import type App from '../core/firebase-app'; import type App from '../core/app';
type AuthState = { type AuthState = {
user?: NativeUser, user?: NativeUser,
}; };
type ActionCodeInfo = {
data: {
email?: string,
fromEmail?: string,
},
operation: 'PASSWORD_RESET' | 'VERIFY_EMAIL' | 'RECOVER_EMAIL',
};
const NATIVE_EVENTS = [ const NATIVE_EVENTS = [
'auth_state_changed', 'auth_state_changed',
'auth_id_token_changed', 'auth_id_token_changed',

View File

@ -3,6 +3,14 @@
*/ */
import type User from './User'; import type User from './User';
export type ActionCodeInfo = {
data: {
email?: string,
fromEmail?: string,
},
operation: 'PASSWORD_RESET' | 'VERIFY_EMAIL' | 'RECOVER_EMAIL',
};
export type ActionCodeSettings = { export type ActionCodeSettings = {
android: { android: {
installApp?: boolean, installApp?: boolean,
@ -16,7 +24,7 @@ export type ActionCodeSettings = {
url: string, url: string,
}; };
type AdditionalUserInfo = { export type AdditionalUserInfo = {
isNewUser: boolean, isNewUser: boolean,
profile?: Object, profile?: Object,
providerId: string, providerId: string,

View File

@ -6,7 +6,7 @@ import { getLogger } from '../../utils/log';
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
type NativeValue = { type NativeValue = {
stringValue?: string, stringValue?: string,
@ -123,7 +123,7 @@ export default class RemoteConfig extends ModuleBase {
* "source" : OneOf<String>(remoteConfigSourceRemote|remoteConfigSourceDefault|remoteConfigSourceStatic) * "source" : OneOf<String>(remoteConfigSourceRemote|remoteConfigSourceDefault|remoteConfigSourceStatic)
* } * }
*/ */
getValue(key: String) { getValue(key: string) {
return getNativeModule(this) return getNativeModule(this)
.getValue(key || '') .getValue(key || '')
.then(this._nativeValueToJS); .then(this._nativeValueToJS);
@ -160,7 +160,7 @@ export default class RemoteConfig extends ModuleBase {
* @param prefix: The key prefix to look for. If prefix is nil or empty, returns all the keys. * @param prefix: The key prefix to look for. If prefix is nil or empty, returns all the keys.
* @returns {*|Promise.<Array<String>>} * @returns {*|Promise.<Array<String>>}
*/ */
getKeysByPrefix(prefix?: String) { getKeysByPrefix(prefix?: string) {
return getNativeModule(this).getKeysByPrefix(prefix); return getNativeModule(this).getKeysByPrefix(prefix);
} }
@ -176,7 +176,7 @@ export default class RemoteConfig extends ModuleBase {
* Sets default configs from plist for default namespace; * Sets default configs from plist for default namespace;
* @param resource: The plist file name or resource ID * @param resource: The plist file name or resource ID
*/ */
setDefaultsFromResource(resource: String | number) { setDefaultsFromResource(resource: string | number) {
getNativeModule(this).setDefaultsFromResource(resource); getNativeModule(this).setDefaultsFromResource(resource);
} }
} }

View File

@ -116,10 +116,12 @@ export default class App {
* @param props * @param props
*/ */
extendApp(props: Object) { extendApp(props: Object) {
if (!isObject(props)) if (!isObject(props)) {
throw new Error( throw new Error(
INTERNALS.STRINGS.ERROR_MISSING_ARG('Object', 'extendApp') 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++) {
@ -129,7 +131,7 @@ export default class App {
throw new Error(INTERNALS.STRINGS.ERROR_PROTECTED_PROP(key)); throw new Error(INTERNALS.STRINGS.ERROR_PROTECTED_PROP(key));
} }
// $FlowBug: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 // $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323
this[key] = props[key]; this[key] = props[key];
this._extendedProps[key] = true; this._extendedProps[key] = true;
} }
@ -167,4 +169,13 @@ export default class App {
}); });
}); });
} }
/**
* toString returns the name of the app.
*
* @return {string}
*/
toString() {
return this._name;
}
} }

View File

@ -1,12 +1,11 @@
/** /**
* @providesModule Firebase
* @flow * @flow
*/ */
import { NativeModules } from 'react-native'; import { NativeModules } from 'react-native';
import APPS from '../../utils/apps'; import APPS from '../../utils/apps';
import INTERNALS from '../../utils/internals'; import INTERNALS from '../../utils/internals';
import App from './firebase-app'; import App from './app';
import VERSION from '../../version'; import VERSION from '../../version';
// module imports // module imports

View File

@ -5,7 +5,7 @@
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
import type { FirebaseError } from '../../types'; import type { FirebaseError } from '../../types';
export const MODULE_NAME = 'RNFirebaseCrash'; export const MODULE_NAME = 'RNFirebaseCrash';

View File

@ -1,15 +1,15 @@
/** /**
* @flow * @flow
* Snapshot representation wrapper * DataSnapshot representation wrapper
*/ */
import { isObject, deepGet, deepExists } from './../../utils'; import { isObject, deepGet, deepExists } from './../../utils';
import type Reference from './reference'; import type Reference from './Reference';
/** /**
* @class DataSnapshot * @class DataSnapshot
* @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot
*/ */
export default class Snapshot { export default class DataSnapshot {
ref: Reference; ref: Reference;
key: string; key: string;
@ -50,10 +50,10 @@ export default class Snapshot {
* @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#forEach * @link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#forEach
* @returns {Snapshot} * @returns {Snapshot}
*/ */
child(path: string): Snapshot { child(path: string): DataSnapshot {
const value = deepGet(this._value, path); const value = deepGet(this._value, path);
const childRef = this.ref.child(path); const childRef = this.ref.child(path);
return new Snapshot(childRef, { return new DataSnapshot(childRef, {
value, value,
key: childRef.key, key: childRef.key,
exists: value !== null, exists: value !== null,

View File

@ -1,17 +1,17 @@
/** /**
* @flow * @flow
* Disconnect representation wrapper * OnDisconnect representation wrapper
*/ */
import { typeOf } from '../../utils'; import { typeOf } from '../../utils';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type Database from './'; import type Database from './';
import type Reference from './reference'; import type Reference from './Reference';
/** /**
* @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect * @url https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect
* @class Disconnect * @class OmDisconnect
*/ */
export default class Disconnect { export default class OnDisconnect {
_database: Database; _database: Database;
ref: Reference; ref: Reference;
path: string; path: string;

View File

@ -5,7 +5,7 @@
import { objectToUniqueId } from '../../utils'; import { objectToUniqueId } from '../../utils';
import type { DatabaseModifier } from '../../types'; import type { DatabaseModifier } from '../../types';
import type Reference from './reference'; import type Reference from './Reference';
// todo doc methods // todo doc methods

View File

@ -2,9 +2,9 @@
* @flow * @flow
* Database Reference representation wrapper * Database Reference representation wrapper
*/ */
import Query from './query'; import Query from './Query';
import Snapshot from './snapshot'; import DataSnapshot from './DataSnapshot';
import Disconnect from './disconnect'; import OnDisconnect from './OnDisconnect';
import { getLogger } from '../../utils/log'; import { getLogger } from '../../utils/log';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import ReferenceBase from '../../utils/ReferenceBase'; import ReferenceBase from '../../utils/ReferenceBase';
@ -218,7 +218,11 @@ export default class Reference extends ReferenceBase {
*/ */
transaction( transaction(
transactionUpdate: Function, transactionUpdate: Function,
onComplete: (error: ?Error, committed: boolean, snapshot: ?Snapshot) => *, onComplete: (
error: ?Error,
committed: boolean,
snapshot: ?DataSnapshot
) => *,
applyLocally: boolean = false applyLocally: boolean = false
) { ) {
if (!isFunction(transactionUpdate)) { if (!isFunction(transactionUpdate)) {
@ -233,14 +237,14 @@ export default class Reference extends ReferenceBase {
if (error) { if (error) {
onComplete(error, committed, null); onComplete(error, committed, null);
} else { } else {
onComplete(null, committed, new Snapshot(this, snapshotData)); onComplete(null, committed, new DataSnapshot(this, snapshotData));
} }
} }
if (error) return reject(error); if (error) return reject(error);
return resolve({ return resolve({
committed, committed,
snapshot: new Snapshot(this, snapshotData), snapshot: new DataSnapshot(this, snapshotData),
}); });
}; };
@ -264,14 +268,14 @@ export default class Reference extends ReferenceBase {
*/ */
once( once(
eventName: string = 'value', eventName: string = 'value',
successCallback: (snapshot: Object) => void, successCallback: (snapshot: DataSnapshot) => void,
cancelOrContext: (error: FirebaseError) => void, cancelOrContext: (error: FirebaseError) => void,
context?: Object context?: Object
) { ) {
return getNativeModule(this._database) return getNativeModule(this._database)
.once(this._getRefKey(), this.path, this._query.getModifiers(), eventName) .once(this._getRefKey(), this.path, this._query.getModifiers(), eventName)
.then(({ snapshot }) => { .then(({ snapshot }) => {
const _snapshot = new Snapshot(this, snapshot); const _snapshot = new DataSnapshot(this, snapshot);
if (isFunction(successCallback)) { if (isFunction(successCallback)) {
if (isObject(cancelOrContext)) if (isObject(cancelOrContext))
@ -313,9 +317,9 @@ export default class Reference extends ReferenceBase {
if (isFunction(onComplete)) { if (isFunction(onComplete)) {
return ( return (
promise promise
// $FlowBug: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655 // $FlowExpectedError: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655
.then(() => onComplete(null, newRef)) .then(() => onComplete(null, newRef))
// $FlowBug: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655 // $FlowExpectedError: Reports that onComplete can change to null despite the null check: https://github.com/facebook/flow/issues/1655
.catch(error => onComplete(error, null)) .catch(error => onComplete(error, null))
); );
} }
@ -470,10 +474,10 @@ export default class Reference extends ReferenceBase {
/** /**
* *
* @returns {Disconnect} * @returns {OnDisconnect}
*/ */
onDisconnect(): Disconnect { onDisconnect(): OnDisconnect {
return new Disconnect(this); return new OnDisconnect(this);
} }
/** /**
@ -691,7 +695,7 @@ export default class Reference extends ReferenceBase {
*/ */
on( on(
eventType: string, eventType: string,
callback: Snapshot => any, callback: DataSnapshot => any,
cancelCallbackOrContext?: Object => any | Object, cancelCallbackOrContext?: Object => any | Object,
context?: Object context?: Object
): Function { ): Function {

View File

@ -4,12 +4,12 @@
*/ */
import { NativeModules } from 'react-native'; import { NativeModules } from 'react-native';
import Reference from './reference'; import Reference from './Reference';
import TransactionHandler from './transaction'; import TransactionHandler from './transaction';
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
const NATIVE_EVENTS = [ const NATIVE_EVENTS = [
'database_transaction_event', 'database_transaction_event',

View File

@ -5,7 +5,7 @@
import ModuleBase from '../../../utils/ModuleBase'; import ModuleBase from '../../../utils/ModuleBase';
import { getNativeModule } from '../../../utils/native'; import { getNativeModule } from '../../../utils/native';
import type App from '../../core/firebase-app'; import type App from '../../core/app';
export const MODULE_NAME = 'RNFirebaseCrashlytics'; export const MODULE_NAME = 'RNFirebaseCrashlytics';
export const NAMESPACE = 'crashlytics'; export const NAMESPACE = 'crashlytics';

View File

@ -8,17 +8,13 @@ import { firestoreAutoId } from '../../utils';
import type Firestore from './'; import type Firestore from './';
import type { import type {
FirestoreQueryDirection, QueryDirection,
FirestoreQueryOperator, QueryListenOptions,
} from '../../types'; QueryOperator,
} from './types';
import type FieldPath from './FieldPath'; import type FieldPath from './FieldPath';
import type Path from './Path'; import type Path from './Path';
import type { import type { Observer, ObserverOnError, ObserverOnNext } from './Query';
Observer,
ObserverOnError,
ObserverOnNext,
QueryListenOptions,
} from './Query';
import type QuerySnapshot from './QuerySnapshot'; import type QuerySnapshot from './QuerySnapshot';
/** /**
@ -95,10 +91,7 @@ export default class CollectionReference {
); );
} }
orderBy( orderBy(fieldPath: string | FieldPath, directionStr?: QueryDirection): Query {
fieldPath: string | FieldPath,
directionStr?: FirestoreQueryDirection
): Query {
return this._query.orderBy(fieldPath, directionStr); return this._query.orderBy(fieldPath, directionStr);
} }
@ -110,7 +103,7 @@ export default class CollectionReference {
return this._query.startAt(snapshotOrVarArgs); return this._query.startAt(snapshotOrVarArgs);
} }
where(fieldPath: string, opStr: FirestoreQueryOperator, value: any): Query { where(fieldPath: string, opStr: QueryOperator, value: any): Query {
return this._query.where(fieldPath, opStr, value); return this._query.where(fieldPath, opStr, value);
} }
} }

View File

@ -5,7 +5,7 @@
import DocumentSnapshot from './DocumentSnapshot'; import DocumentSnapshot from './DocumentSnapshot';
import type Firestore from './'; import type Firestore from './';
import type { FirestoreNativeDocumentChange } from '../../types'; import type { NativeDocumentChange } from './types';
/** /**
* @class DocumentChange * @class DocumentChange
@ -16,7 +16,7 @@ export default class DocumentChange {
_oldIndex: number; _oldIndex: number;
_type: string; _type: string;
constructor(firestore: Firestore, nativeData: FirestoreNativeDocumentChange) { constructor(firestore: Firestore, nativeData: NativeDocumentChange) {
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;

View File

@ -14,15 +14,12 @@ import { getNativeModule } from '../../utils/native';
import type Firestore from './'; import type Firestore from './';
import type { import type {
FirestoreNativeDocumentSnapshot, DocumentListenOptions,
FirestoreWriteOptions, NativeDocumentSnapshot,
} from '../../types'; SetOptions,
} from './types';
import type Path from './Path'; import type Path from './Path';
type DocumentListenOptions = {
includeMetadataChanges: boolean,
};
type ObserverOnError = Object => void; type ObserverOnError = Object => void;
type ObserverOnNext = DocumentSnapshot => void; type ObserverOnNext = DocumentSnapshot => void;
@ -99,7 +96,7 @@ export default class DocumentReference {
'DocumentReference.onSnapshot failed: Second argument must be a valid function.' 'DocumentReference.onSnapshot failed: Second argument must be a valid function.'
); );
} }
// $FlowBug: Not coping with the overloaded method signature // $FlowExpectedError: Not coping with the overloaded method signature
observer = { observer = {
next: optionsOrObserverOrOnNext, next: optionsOrObserverOrOnNext,
error: observerOrOnNextOrOnError, error: observerOrOnNextOrOnError,
@ -119,7 +116,7 @@ export default class DocumentReference {
'DocumentReference.onSnapshot failed: Observer.error must be a valid function.' 'DocumentReference.onSnapshot failed: Observer.error must be a valid function.'
); );
} }
// $FlowBug: Not coping with the overloaded method signature // $FlowExpectedError: Not coping with the overloaded method signature
observer = { observer = {
next: optionsOrObserverOrOnNext.next, next: optionsOrObserverOrOnNext.next,
error: optionsOrObserverOrOnNext.error, error: optionsOrObserverOrOnNext.error,
@ -143,7 +140,7 @@ export default class DocumentReference {
'DocumentReference.onSnapshot failed: Third argument must be a valid function.' 'DocumentReference.onSnapshot failed: Third argument must be a valid function.'
); );
} }
// $FlowBug: Not coping with the overloaded method signature // $FlowExpectedError: Not coping with the overloaded method signature
observer = { observer = {
next: observerOrOnNextOrOnError, next: observerOrOnNextOrOnError,
error: onError, error: onError,
@ -189,9 +186,7 @@ export default class DocumentReference {
} }
const listenerId = firestoreAutoId(); const listenerId = firestoreAutoId();
const listener = ( const listener = (nativeDocumentSnapshot: NativeDocumentSnapshot) => {
nativeDocumentSnapshot: FirestoreNativeDocumentSnapshot
) => {
const documentSnapshot = new DocumentSnapshot( const documentSnapshot = new DocumentSnapshot(
this.firestore, this.firestore,
nativeDocumentSnapshot nativeDocumentSnapshot
@ -227,12 +222,12 @@ export default class DocumentReference {
return this._offDocumentSnapshot.bind(this, listenerId, listener); return this._offDocumentSnapshot.bind(this, listenerId, listener);
} }
set(data: Object, writeOptions?: FirestoreWriteOptions): Promise<void> { set(data: Object, options?: SetOptions): Promise<void> {
const nativeData = buildNativeMap(data); const nativeData = buildNativeMap(data);
return getNativeModule(this._firestore).documentSet( return getNativeModule(this._firestore).documentSet(
this.path, this.path,
nativeData, nativeData,
writeOptions options
); );
} }

View File

@ -9,10 +9,7 @@ import { isObject } from '../../utils';
import { parseNativeMap } from './utils/serialize'; import { parseNativeMap } from './utils/serialize';
import type Firestore from './'; import type Firestore from './';
import type { import type { NativeDocumentSnapshot, SnapshotMetadata } from './types';
FirestoreNativeDocumentSnapshot,
FirestoreSnapshotMetadata,
} from '../../types';
const extractFieldPathData = (data: Object | void, segments: string[]): any => { const extractFieldPathData = (data: Object | void, segments: string[]): any => {
if (!data || !isObject(data)) { if (!data || !isObject(data)) {
@ -30,13 +27,10 @@ const extractFieldPathData = (data: Object | void, segments: string[]): any => {
*/ */
export default class DocumentSnapshot { export default class DocumentSnapshot {
_data: Object | void; _data: Object | void;
_metadata: FirestoreSnapshotMetadata; _metadata: SnapshotMetadata;
_ref: DocumentReference; _ref: DocumentReference;
constructor( constructor(firestore: Firestore, nativeData: NativeDocumentSnapshot) {
firestore: Firestore,
nativeData: FirestoreNativeDocumentSnapshot
) {
this._data = parseNativeMap(firestore, nativeData.data); this._data = parseNativeMap(firestore, nativeData.data);
this._metadata = nativeData.metadata; this._metadata = nativeData.metadata;
this._ref = new DocumentReference( this._ref = new DocumentReference(
@ -53,7 +47,7 @@ export default class DocumentSnapshot {
return this._ref.id; return this._ref.id;
} }
get metadata(): FirestoreSnapshotMetadata { get metadata(): SnapshotMetadata {
return this._metadata; return this._metadata;
} }

View File

@ -12,20 +12,21 @@ import { firestoreAutoId, isFunction, isObject } from '../../utils';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type Firestore from './'; import type Firestore from './';
import type {
FirestoreQueryDirection,
FirestoreQueryOperator,
} from '../../types';
import type Path from './Path'; import type Path from './Path';
import type {
QueryDirection,
QueryOperator,
QueryListenOptions,
} from './types';
const DIRECTIONS: { [FirestoreQueryDirection]: string } = { const DIRECTIONS: { [QueryDirection]: string } = {
ASC: 'ASCENDING', ASC: 'ASCENDING',
asc: 'ASCENDING', asc: 'ASCENDING',
DESC: 'DESCENDING', DESC: 'DESCENDING',
desc: 'DESCENDING', desc: 'DESCENDING',
}; };
const OPERATORS: { [FirestoreQueryOperator]: string } = { const OPERATORS: { [QueryOperator]: string } = {
'=': 'EQUAL', '=': 'EQUAL',
'==': 'EQUAL', '==': 'EQUAL',
'>': 'GREATER_THAN', '>': 'GREATER_THAN',
@ -58,11 +59,6 @@ type QueryOptions = {
startAt?: any[], startAt?: any[],
}; };
export type QueryListenOptions = {|
includeDocumentMetadataChanges: boolean,
includeQueryMetadataChanges: boolean,
|};
export type ObserverOnError = Object => void; export type ObserverOnError = Object => void;
export type ObserverOnNext = QuerySnapshot => void; export type ObserverOnNext = QuerySnapshot => void;
@ -187,7 +183,7 @@ export default class Query {
'Query.onSnapshot failed: Second argument must be a valid function.' 'Query.onSnapshot failed: Second argument must be a valid function.'
); );
} }
// $FlowBug: Not coping with the overloaded method signature // $FlowExpectedError: Not coping with the overloaded method signature
observer = { observer = {
next: optionsOrObserverOrOnNext, next: optionsOrObserverOrOnNext,
error: observerOrOnNextOrOnError, error: observerOrOnNextOrOnError,
@ -207,7 +203,7 @@ export default class Query {
'Query.onSnapshot failed: Observer.error must be a valid function.' 'Query.onSnapshot failed: Observer.error must be a valid function.'
); );
} }
// $FlowBug: Not coping with the overloaded method signature // $FlowExpectedError: Not coping with the overloaded method signature
observer = { observer = {
next: optionsOrObserverOrOnNext.next, next: optionsOrObserverOrOnNext.next,
error: optionsOrObserverOrOnNext.error, error: optionsOrObserverOrOnNext.error,
@ -235,7 +231,7 @@ export default class Query {
'Query.onSnapshot failed: Third argument must be a valid function.' 'Query.onSnapshot failed: Third argument must be a valid function.'
); );
} }
// $FlowBug: Not coping with the overloaded method signature // $FlowExpectedError: Not coping with the overloaded method signature
observer = { observer = {
next: observerOrOnNextOrOnError, next: observerOrOnNextOrOnError,
error: onError, error: onError,
@ -320,7 +316,7 @@ export default class Query {
orderBy( orderBy(
fieldPath: string | FieldPath, fieldPath: string | FieldPath,
directionStr?: FirestoreQueryDirection = 'asc' directionStr?: QueryDirection = 'asc'
): Query { ): Query {
// TODO: Validation // TODO: Validation
// validate.isFieldPath('fieldPath', fieldPath); // validate.isFieldPath('fieldPath', fieldPath);
@ -379,7 +375,7 @@ export default class Query {
where( where(
fieldPath: string | FieldPath, fieldPath: string | FieldPath,
opStr: FirestoreQueryOperator, opStr: QueryOperator,
value: any value: any
): Query { ): Query {
// TODO: Validation // TODO: Validation

View File

@ -7,16 +7,16 @@ import DocumentSnapshot from './DocumentSnapshot';
import type Firestore from './'; import type Firestore from './';
import type { import type {
FirestoreNativeDocumentChange, NativeDocumentChange,
FirestoreNativeDocumentSnapshot, NativeDocumentSnapshot,
FirestoreSnapshotMetadata, SnapshotMetadata,
} from '../../types'; } from './types';
import type Query from './Query'; import type Query from './Query';
type QuerySnapshotNativeData = { type NativeQuerySnapshot = {
changes: FirestoreNativeDocumentChange[], changes: NativeDocumentChange[],
documents: FirestoreNativeDocumentSnapshot[], documents: NativeDocumentSnapshot[],
metadata: FirestoreSnapshotMetadata, metadata: SnapshotMetadata,
}; };
/** /**
@ -25,13 +25,13 @@ type QuerySnapshotNativeData = {
export default class QuerySnapshot { export default class QuerySnapshot {
_changes: DocumentChange[]; _changes: DocumentChange[];
_docs: DocumentSnapshot[]; _docs: DocumentSnapshot[];
_metadata: FirestoreSnapshotMetadata; _metadata: SnapshotMetadata;
_query: Query; _query: Query;
constructor( constructor(
firestore: Firestore, firestore: Firestore,
query: Query, query: Query,
nativeData: QuerySnapshotNativeData nativeData: NativeQuerySnapshot
) { ) {
this._changes = nativeData.changes.map( this._changes = nativeData.changes.map(
change => new DocumentChange(firestore, change) change => new DocumentChange(firestore, change)
@ -55,7 +55,7 @@ export default class QuerySnapshot {
return this._docs.length === 0; return this._docs.length === 0;
} }
get metadata(): FirestoreSnapshotMetadata { get metadata(): SnapshotMetadata {
return this._metadata; return this._metadata;
} }

View File

@ -10,7 +10,7 @@ import { getNativeModule } from '../../utils/native';
import type DocumentReference from './DocumentReference'; import type DocumentReference from './DocumentReference';
import type Firestore from './'; import type Firestore from './';
import type { FirestoreWriteOptions } from '../../types'; import type { SetOptions } from './types';
type DocumentWrite = { type DocumentWrite = {
data?: Object, data?: Object,
@ -47,19 +47,15 @@ export default class WriteBatch {
return this; return this;
} }
set( set(docRef: DocumentReference, data: Object, options?: SetOptions) {
docRef: DocumentReference,
data: Object,
writeOptions?: FirestoreWriteOptions
) {
// TODO: Validation // TODO: Validation
// validate.isDocumentReference('docRef', docRef); // validate.isDocumentReference('docRef', docRef);
// validate.isDocument('data', data); // validate.isDocument('data', data);
// validate.isOptionalPrecondition('writeOptions', writeOptions); // validate.isOptionalPrecondition('options', writeOptions);
const nativeData = buildNativeMap(data); const nativeData = buildNativeMap(data);
this._writes.push({ this._writes.push({
data: nativeData, data: nativeData,
options: writeOptions, options,
path: docRef.path, path: docRef.path,
type: 'SET', type: 'SET',
}); });

View File

@ -18,7 +18,7 @@ import Transaction from './Transaction';
import INTERNALS from '../../utils/internals'; import INTERNALS from '../../utils/internals';
import type DocumentSnapshot from './DocumentSnapshot'; import type DocumentSnapshot from './DocumentSnapshot';
import type App from '../core/firebase-app'; import type App from '../core/app';
import type QuerySnapshot from './QuerySnapshot'; import type QuerySnapshot from './QuerySnapshot';
type CollectionSyncEvent = { type CollectionSyncEvent = {

View File

@ -0,0 +1,54 @@
/*
* @flow
*/
export type DocumentListenOptions = {
includeMetadataChanges: boolean,
};
export type QueryDirection = 'DESC' | 'desc' | 'ASC' | 'asc';
export type QueryListenOptions = {|
includeDocumentMetadataChanges: boolean,
includeQueryMetadataChanges: boolean,
|};
export type QueryOperator = '<' | '<=' | '=' | '==' | '>' | '>=';
export type SetOptions = {
merge?: boolean,
};
export type SnapshotMetadata = {
fromCache: boolean,
hasPendingWrites: boolean,
};
export type NativeDocumentChange = {
document: NativeDocumentSnapshot,
newIndex: number,
oldIndex: number,
type: string,
};
export type NativeDocumentSnapshot = {
data: { [string]: NativeTypeMap },
metadata: SnapshotMetadata,
path: string,
};
export type NativeTypeMap = {
type:
| 'array'
| 'boolean'
| 'date'
| 'documentid'
| 'fieldvalue'
| 'geopoint'
| 'null'
| 'number'
| 'object'
| 'reference'
| 'string',
value: any,
};

View File

@ -13,7 +13,7 @@ import Path from '../Path';
import { typeOf } from '../../../utils'; import { typeOf } from '../../../utils';
import type Firestore from '../'; import type Firestore from '../';
import type { FirestoreTypeMap } from '../../../types'; import type { NativeTypeMap } from '../types';
/* /*
* Functions that build up the data needed to represent * Functions that build up the data needed to represent
@ -21,9 +21,7 @@ import type { FirestoreTypeMap } from '../../../types';
* for transmission to the native side * for transmission to the native side
*/ */
export const buildNativeMap = ( export const buildNativeMap = (data: Object): { [string]: NativeTypeMap } => {
data: Object
): { [string]: FirestoreTypeMap } => {
const nativeData = {}; const nativeData = {};
if (data) { if (data) {
Object.keys(data).forEach(key => { Object.keys(data).forEach(key => {
@ -36,7 +34,7 @@ export const buildNativeMap = (
return nativeData; return nativeData;
}; };
export const buildNativeArray = (array: Object[]): FirestoreTypeMap[] => { export const buildNativeArray = (array: Object[]): NativeTypeMap[] => {
const nativeArray = []; const nativeArray = [];
if (array) { if (array) {
array.forEach(value => { array.forEach(value => {
@ -49,7 +47,7 @@ export const buildNativeArray = (array: Object[]): FirestoreTypeMap[] => {
return nativeArray; return nativeArray;
}; };
export const buildTypeMap = (value: any): FirestoreTypeMap | null => { export const buildTypeMap = (value: any): NativeTypeMap | null => {
const type = typeOf(value); const type = typeOf(value);
if (value === null || value === undefined || Number.isNaN(value)) { if (value === null || value === undefined || Number.isNaN(value)) {
return { return {
@ -117,7 +115,7 @@ export const buildTypeMap = (value: any): FirestoreTypeMap | null => {
export const parseNativeMap = ( export const parseNativeMap = (
firestore: Firestore, firestore: Firestore,
nativeData: { [string]: FirestoreTypeMap } nativeData: { [string]: NativeTypeMap }
): Object | void => { ): Object | void => {
let data; let data;
if (nativeData) { if (nativeData) {
@ -131,7 +129,7 @@ export const parseNativeMap = (
const parseNativeArray = ( const parseNativeArray = (
firestore: Firestore, firestore: Firestore,
nativeArray: FirestoreTypeMap[] nativeArray: NativeTypeMap[]
): any[] => { ): any[] => {
const array = []; const array = [];
if (nativeArray) { if (nativeArray) {
@ -142,7 +140,7 @@ const parseNativeArray = (
return array; return array;
}; };
const parseTypeMap = (firestore: Firestore, typeMap: FirestoreTypeMap): any => { const parseTypeMap = (firestore: Firestore, typeMap: NativeTypeMap): any => {
const { type, value } = typeMap; const { type, value } = typeMap;
if (type === 'null') { if (type === 'null') {
return null; return null;

View File

@ -7,7 +7,7 @@ import ModuleBase from '../../utils/ModuleBase';
import { areObjectKeysContainedInOther, isObject, isString } from '../../utils'; import { areObjectKeysContainedInOther, isObject, isString } from '../../utils';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
const EVENT_TYPE = { const EVENT_TYPE = {
Link: 'dynamic_link_received', Link: 'dynamic_link_received',

View File

@ -8,7 +8,7 @@ import ModuleBase from '../../utils/ModuleBase';
import RemoteMessage from './RemoteMessage'; import RemoteMessage from './RemoteMessage';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
const EVENT_TYPE = { const EVENT_TYPE = {
RefreshToken: 'messaging_token_refreshed', RefreshToken: 'messaging_token_refreshed',

View File

@ -6,7 +6,7 @@ import Trace from './Trace';
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
export const MODULE_NAME = 'RNFirebasePerformance'; export const MODULE_NAME = 'RNFirebasePerformance';
export const NAMESPACE = 'perf'; export const NAMESPACE = 'perf';

View File

@ -10,7 +10,7 @@ import { getLogger } from '../../utils/log';
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/firebase-app'; import type App from '../core/app';
const FirebaseStorage = NativeModules.RNFirebaseStorage; const FirebaseStorage = NativeModules.RNFirebaseStorage;

View File

@ -92,7 +92,7 @@ export default class StorageTask {
if (!isFunction(f)) return null; if (!isFunction(f)) return null;
return error => { return error => {
const _error = new Error(error.message); const _error = new Error(error.message);
// $FlowFixMe // $FlowExpectedError
_error.code = error.code; _error.code = error.code;
return f && f(_error); return f && f(_error);
}; };

View File

@ -3,7 +3,7 @@ import { NativeModules } from 'react-native';
import INTERNALS from '../../utils/internals'; import INTERNALS from '../../utils/internals';
import { isIOS } from '../../utils'; import { isIOS } from '../../utils';
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import type App from '../core/firebase-app'; import type App from '../core/app';
const FirebaseCoreModule = NativeModules.RNFirebase; const FirebaseCoreModule = NativeModules.RNFirebase;

View File

@ -162,47 +162,6 @@ export type FirestoreModule = {
nativeModuleExists: boolean, nativeModuleExists: boolean,
} & FirestoreStatics; } & FirestoreStatics;
export type FirestoreNativeDocumentChange = {
document: FirestoreNativeDocumentSnapshot,
newIndex: number,
oldIndex: number,
type: string,
};
export type FirestoreNativeDocumentSnapshot = {
data: { [string]: FirestoreTypeMap },
metadata: FirestoreSnapshotMetadata,
path: string,
};
export type FirestoreSnapshotMetadata = {
fromCache: boolean,
hasPendingWrites: boolean,
};
export type FirestoreQueryDirection = 'DESC' | 'desc' | 'ASC' | 'asc';
export type FirestoreQueryOperator = '<' | '<=' | '=' | '==' | '>' | '>=';
export type FirestoreTypeMap = {
type:
| 'array'
| 'boolean'
| 'date'
| 'documentid'
| 'fieldvalue'
| 'geopoint'
| 'null'
| 'number'
| 'object'
| 'reference'
| 'string',
value: any,
};
export type FirestoreWriteOptions = {
merge?: boolean,
};
/* Links types */ /* Links types */
export type LinksModule = { export type LinksModule = {

View File

@ -4,7 +4,7 @@
import { initialiseLogger } from './log'; import { initialiseLogger } from './log';
import { initialiseNativeModule } from './native'; import { initialiseNativeModule } from './native';
import type App from '../modules/core/firebase-app'; import type App from '../modules/core/app';
import type { FirebaseModuleConfig, FirebaseNamespace } from '../types'; import type { FirebaseModuleConfig, FirebaseNamespace } from '../types';
export default class ModuleBase { export default class ModuleBase {

View File

@ -4,11 +4,11 @@
import { NativeEventEmitter, NativeModules } from 'react-native'; import { NativeEventEmitter, NativeModules } from 'react-native';
import { SharedEventEmitter } from './events'; import { SharedEventEmitter } from './events';
import DatabaseSnapshot from '../modules/database/snapshot'; import DataSnapshot from '../modules/database/DataSnapshot';
import DatabaseReference from '../modules/database/reference'; import DatabaseReference from '../modules/database/Reference';
import { isString, nativeToJSError } from '../utils'; import { isString, nativeToJSError } from '../utils';
type Listener = DatabaseSnapshot => any; type Listener = DataSnapshot => any;
type Registration = { type Registration = {
key: string, key: string,
@ -83,7 +83,7 @@ class SyncTree {
// forward on to users .on(successCallback <-- listener // forward on to users .on(successCallback <-- listener
return SharedEventEmitter.emit( return SharedEventEmitter.emit(
eventRegistrationKey, eventRegistrationKey,
new DatabaseSnapshot(registration.ref, snapshot), new DataSnapshot(registration.ref, snapshot),
previousChildName previousChildName
); );
} }

View File

@ -2,7 +2,7 @@
* @flow * @flow
*/ */
import { NativeModules } from 'react-native'; import { NativeModules } from 'react-native';
import App from '../modules/core/firebase-app'; import App from '../modules/core/app';
import INTERNALS from './internals'; import INTERNALS from './internals';
import { isAndroid, isObject, isString } from './'; import { isAndroid, isObject, isString } from './';
@ -32,13 +32,14 @@ export default {
}, },
apps(): Array<App> { apps(): Array<App> {
// $FlowBug: Object.values always returns mixed type: https://github.com/facebook/flow/issues/2221 // $FlowExpectedError: Object.values always returns mixed type: https://github.com/facebook/flow/issues/2221
return Object.values(APPS); return Object.values(APPS);
}, },
/** /**
* *
* @param statics * @param app
* @param namespace
* @param InstanceClass * @param InstanceClass
* @return {function()} * @return {function()}
* @private * @private
@ -152,8 +153,9 @@ export default {
/** /**
* *
* @param namespace
* @param statics * @param statics
* @param InstanceClass * @param moduleName
* @return {function(App=)} * @return {function(App=)}
*/ */
moduleAndStatics<M: FirebaseModule, S: FirebaseStatics>( moduleAndStatics<M: FirebaseModule, S: FirebaseStatics>(
@ -174,7 +176,7 @@ export default {
if (namespace === 'crashlytics') { if (namespace === 'crashlytics') {
return _app.fabric[namespace](); return _app.fabric[namespace]();
} }
// $FlowBug: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 // $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323
const module = _app[namespace]; const module = _app[namespace];
return module(); return module();
}; };

View File

@ -201,7 +201,7 @@ class EventEmitter {
* }); // removes the listener if already registered * }); // removes the listener if already registered
* *
*/ */
removeListener(eventType: String, listener) { removeListener(eventType: string, listener) {
const subscriptions: ?[EmitterSubscription] = (this._subscriber.getSubscriptionsForType(eventType): any); const subscriptions: ?[EmitterSubscription] = (this._subscriber.getSubscriptionsForType(eventType): any);
if (subscriptions) { if (subscriptions) {
for (let i = 0, l = subscriptions.length; i < l; i++) { for (let i = 0, l = subscriptions.length; i < l; i++) {

View File

@ -282,7 +282,7 @@ export function typeOf(value: any): string {
// * @param string // * @param string
// * @return {string} // * @return {string}
// */ // */
// export function capitalizeFirstLetter(string: String) { // export function capitalizeFirstLetter(string: string) {
// return `${string.charAt(0).toUpperCase()}${string.slice(1)}`; // return `${string.charAt(0).toUpperCase()}${string.slice(1)}`;
// } // }

View File

@ -21,35 +21,35 @@ const GRADLE_DEPS = {
}; };
const PLAY_SERVICES_CODES = { const PLAY_SERVICES_CODES = {
// $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380
1: { 1: {
code: 'SERVICE_MISSING', code: 'SERVICE_MISSING',
message: 'Google Play services is missing on this device.', message: 'Google Play services is missing on this device.',
}, },
// $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380
2: { 2: {
code: 'SERVICE_VERSION_UPDATE_REQUIRED', code: 'SERVICE_VERSION_UPDATE_REQUIRED',
message: message:
'The installed version of Google Play services on this device is out of date.', 'The installed version of Google Play services on this device is out of date.',
}, },
// $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380
3: { 3: {
code: 'SERVICE_DISABLED', code: 'SERVICE_DISABLED',
message: message:
'The installed version of Google Play services has been disabled on this device.', 'The installed version of Google Play services has been disabled on this device.',
}, },
// $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380
9: { 9: {
code: 'SERVICE_INVALID', code: 'SERVICE_INVALID',
message: message:
'The version of the Google Play services installed on this device is not authentic.', 'The version of the Google Play services installed on this device is not authentic.',
}, },
// $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380
18: { 18: {
code: 'SERVICE_UPDATING', code: 'SERVICE_UPDATING',
message: 'Google Play services is currently being updated on this device.', message: 'Google Play services is currently being updated on this device.',
}, },
// $FlowBug: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380 // $FlowExpectedError: Doesn't like numerical object keys: https://github.com/facebook/flow/issues/380
19: { 19: {
code: 'SERVICE_MISSING_PERMISSION', code: 'SERVICE_MISSING_PERMISSION',
message: message:

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "react-native-firebase", "name": "react-native-firebase",
"version": "3.2.4", "version": "3.2.7",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "react-native-firebase", "name": "react-native-firebase",
"version": "3.2.4", "version": "3.2.7",
"author": "Invertase <contact@invertase.io> (http://invertase.io)", "author": "Invertase <contact@invertase.io> (http://invertase.io)",
"description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Messaging (FCM), Remote Config, Storage and Performance.", "description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Messaging (FCM), Remote Config, Storage and Performance.",
"main": "dist/index.js", "main": "dist/index.js",
@ -35,7 +35,7 @@
"unmockedModulePathPatterns": ["./node_modules/react", "./node_modules/react-native", "./node_modules/react-native-mock", "./node_modules/react-addons-test-utils"] "unmockedModulePathPatterns": ["./node_modules/react", "./node_modules/react-native", "./node_modules/react-native-mock", "./node_modules/react-addons-test-utils"]
}, },
"license": "APACHE-2.0", "license": "APACHE-2.0",
"keywords": ["react", "admob", "auth", "config", "digits", "phone-auth", "sms", "firestore", "cloud-firestore", "datastore", "remote-config", "transactions", "react-native", "react-native-firebase", "firebase", "fcm", "apn", "gcm", "analytics", "messaging", "database", "android", "ios", "crash", "firestack", "performance", "firestore", "dynamic-links", "crashlytics"], "keywords": ["react", "admob", "auth", "config", "digits", "fabric", "phone-auth", "sms", "firestore", "cloud-firestore", "datastore", "remote-config", "transactions", "react-native", "react-native-firebase", "firebase", "fcm", "apn", "gcm", "analytics", "messaging", "database", "android", "ios", "crash", "firestack", "performance", "firestore", "dynamic-links", "crashlytics"],
"peerDependencies": { "peerDependencies": {
"react": "*", "react": "*",
"react-native": ">= 0.48.0", "react-native": ">= 0.48.0",

View File

@ -1,7 +1,7 @@
import { Platform } from 'react-native'; import { Platform } from 'react-native';
import should from 'should'; import should from 'should';
import RNFirebase from './../../../firebase'; import firebase from './../../../firebase';
const androidTestConfig = { const androidTestConfig = {
// firebase android sdk completely ignores client id // firebase android sdk completely ignores client id
@ -33,52 +33,47 @@ function rand(from = 1, to = 9999) {
} }
function coreTests({ describe, it }) { function coreTests({ describe, it }) {
describe('Core', () => { describe('Firebase', () => {
it('it should create js apps for natively initialized apps', () => { it('it should create js apps for natively initialized apps', () => {
should.equal(RNFirebase.app()._nativeInitialized, true); should.equal(firebase.app()._nativeInitialized, true);
return Promise.resolve(); return Promise.resolve();
}); });
it('natively initialized apps should have options available in js', () => { it('natively initialized apps should have options available in js', () => {
should.equal( should.equal(
RNFirebase.app().options.apiKey, firebase.app().options.apiKey,
Platform.OS === 'ios' ? iosTestConfig.apiKey : androidTestConfig.apiKey Platform.OS === 'ios' ? iosTestConfig.apiKey : androidTestConfig.apiKey
); );
should.equal( should.equal(
RNFirebase.app().options.appId, firebase.app().options.appId,
Platform.OS === 'ios' ? iosTestConfig.appId : androidTestConfig.appId Platform.OS === 'ios' ? iosTestConfig.appId : androidTestConfig.appId
); );
should.equal( should.equal(
RNFirebase.app().options.databaseURL, firebase.app().options.databaseURL,
iosTestConfig.databaseURL iosTestConfig.databaseURL
); );
should.equal( should.equal(
RNFirebase.app().options.messagingSenderId, firebase.app().options.messagingSenderId,
iosTestConfig.messagingSenderId iosTestConfig.messagingSenderId
); );
should.equal(RNFirebase.app().options.projectId, iosTestConfig.projectId); should.equal(firebase.app().options.projectId, iosTestConfig.projectId);
should.equal( should.equal(
RNFirebase.app().options.storageBucket, firebase.app().options.storageBucket,
iosTestConfig.storageBucket iosTestConfig.storageBucket
); );
return Promise.resolve(); return Promise.resolve();
}); });
it('it should resolve onReady for natively initialized apps', () => it('it should resolve onReady for natively initialized apps', () =>
RNFirebase.app().onReady()); firebase.app().onReady());
it('it should provide an array of apps', () => {
should.equal(!!RNFirebase.apps.length, true);
should.equal(RNFirebase.apps.includes(RNFirebase.app('[DEFAULT]')), true);
return Promise.resolve();
});
it('it should initialize dynamic apps', () => { it('it should initialize dynamic apps', () => {
const name = `testscoreapp${rand()}`; const name = `testscoreapp${rand()}`;
return RNFirebase.initializeApp( return firebase
Platform.OS === 'ios' ? iosTestConfig : androidTestConfig, .initializeApp(
name Platform.OS === 'ios' ? iosTestConfig : androidTestConfig,
) name
)
.onReady() .onReady()
.then(newApp => { .then(newApp => {
newApp.name.should.equal(name.toUpperCase()); newApp.name.should.equal(name.toUpperCase());
@ -90,6 +85,52 @@ function coreTests({ describe, it }) {
return Promise.resolve(); return Promise.resolve();
}); });
}); });
it('SDK_VERSION should return a string version', () => {
firebase.SDK_VERSION.should.be.a.String();
});
});
describe('App', () => {
it('apps should provide an array of apps', () => {
should.equal(!!firebase.apps.length, true);
should.equal(firebase.apps.includes(firebase.app('[DEFAULT]')), true);
return Promise.resolve();
});
it('delete is unsupported', () => {
(() => {
firebase.app().delete();
}).should.throw(
'app.delete() is unsupported by the native Firebase SDKs.'
);
});
it('extendApp should error if an object is not supplied', () => {
(() => {
firebase.app().extendApp('string');
}).should.throw(
"Missing required argument of type 'Object' for method 'extendApp()'."
);
});
it('extendApp should error if a protected property is supplied', () => {
(() => {
firebase.app().extendApp({
database: {},
});
}).should.throw(
"Property 'database' is protected and can not be overridden by extendApp."
);
});
it('extendApp should provide additional functionality', () => {
const extension = {};
firebase.app().extendApp({
extension,
});
firebase.app().extension.should.equal(extension);
});
}); });
} }