diff --git a/lib/firebase.js b/lib/firebase.js index 48df2287..917df680 100644 --- a/lib/firebase.js +++ b/lib/firebase.js @@ -24,15 +24,6 @@ import Utils, { statics as UtilsStatics } from './modules/utils'; const FirebaseCoreModule = NativeModules.RNFirebase; -export type FirebaseOptions = { - apiKey: string, - appId: string, - databaseURL: string, - messagingSenderId: string, - projectId: string, - storageBucket: string, -} - class FirebaseCore { _nativeEmitters: { [string]: NativeEventEmitter }; _nativeSubscriptions: { [string]: boolean }; diff --git a/lib/flow.js b/lib/flow.js index f5295758..71c478e8 100644 --- a/lib/flow.js +++ b/lib/flow.js @@ -1,20 +1,39 @@ /* eslint-disable */ -// declare module 'react-native' { -// // noinspection ES6ConvertVarToLetConst -// declare var exports: any; -// } +/* Core types */ +declare class FirebaseError { + message: string, + name: string, + code: string, + stack: string, + path: string, + details: string, + modifiers: string +}; -declare type AuthResultType = { +declare type FirebaseOptions = { + apiKey: string, + appId: string, + databaseURL: string, + messagingSenderId: string, + projectId: string, + storageBucket: string, +} + +/* Auth types */ + +declare type AuthResult = { authenticated: boolean, user: Object|null } | null; -declare type CredentialType = { +declare type AuthCredential = { providerId: string, token: string, secret: string }; +/* Database types */ + declare type DatabaseListener = { listenerId: number; eventName: string; @@ -31,6 +50,40 @@ declare type DatabaseModifier = { valueType?: string; }; +/* Firestore types */ + +declare type FirestoreNativeDocumentChange = { + document: FirestoreNativeDocumentSnapshot, + newIndex: number, + oldIndex: number, + type: string, +} + +declare type FirestoreNativeDocumentSnapshot = { + data: { [string]: FirestoreTypeMap }, + metadata: FirestoreSnapshotMetadata, + path: string, +} + +declare type FirestoreSnapshotMetadata = { + fromCache: boolean, + hasPendingWrites: boolean, +} + +declare type FirestoreQueryDirection = 'DESC' | 'desc' | 'ASC' | 'asc'; +declare type FirestoreQueryOperator = '<' | '<=' | '=' | '==' | '>' | '>='; + +declare type FirestoreTypeMap = { + type: 'array' | 'boolean' | 'date' | 'fieldvalue' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string', + value: any, +} + +declare type FirestoreWriteOptions = { + merge?: boolean, +} + +/* Util types */ + declare type GoogleApiAvailabilityType = { status: number, isAvailable: boolean, @@ -38,13 +91,3 @@ declare type GoogleApiAvailabilityType = { hasResolution?: boolean, error?: string }; - -declare class FirebaseError { - message: string, - name: string, - code: string, - stack: string, - path: string, - details: string, - modifiers: string -}; diff --git a/lib/modules/auth/ConfirmationResult.js b/lib/modules/auth/ConfirmationResult.js index 0c1c09b3..a2b80b72 100644 --- a/lib/modules/auth/ConfirmationResult.js +++ b/lib/modules/auth/ConfirmationResult.js @@ -1,8 +1,12 @@ /** - * @url https://firebase.google.com/docs/reference/js/firebase.User + * @flow + * ConfirmationResult representation wrapper */ +import type Auth from './'; +import type User from './User'; + export default class ConfirmationResult { - _auth: Object; + _auth: Auth; _verificationId: string; /** @@ -10,7 +14,7 @@ export default class ConfirmationResult { * @param auth * @param verificationId The phone number authentication operation's verification ID. */ - constructor(auth: Object, verificationId: string) { + constructor(auth: Auth, verificationId: string) { this._auth = auth; this._verificationId = verificationId; } @@ -20,13 +24,11 @@ export default class ConfirmationResult { * @param verificationCode * @return {*} */ - confirm(verificationCode: string): Promise { - return this._auth._interceptUserValue( - this._auth._native._confirmVerificationCode(verificationCode) - ); + confirm(verificationCode: string): Promise { + return this._auth._interceptUserValue(this._auth._native._confirmVerificationCode(verificationCode)); } - get verificationId(): String | null { + get verificationId(): string | null { return this._verificationId; } } diff --git a/lib/modules/auth/PhoneAuthListener.js b/lib/modules/auth/PhoneAuthListener.js index 620ad7f1..170aa370 100644 --- a/lib/modules/auth/PhoneAuthListener.js +++ b/lib/modules/auth/PhoneAuthListener.js @@ -2,6 +2,8 @@ import INTERNALS from './../../internals'; import { generatePushID, isFunction, isAndroid, isIOS, isString, nativeToJSError } from './../../utils'; +import type Auth from './'; + type PhoneAuthSnapshot = { state: 'sent' | 'timeout' | 'verified' | 'error', verificationId: string, @@ -17,7 +19,6 @@ type PhoneAuthError = { }; export default class PhoneAuthListener { - _auth: Object; _timeout: number; _publicEvents: Object; @@ -34,7 +35,7 @@ export default class PhoneAuthListener { * @param phoneNumber * @param timeout */ - constructor(auth: Object, phoneNumber: string, timeout?: number) { + constructor(auth: Auth, phoneNumber: string, timeout?: number) { this._auth = auth; this._reject = null; this._resolve = null; diff --git a/lib/modules/auth/Usera.js b/lib/modules/auth/User.js similarity index 52% rename from lib/modules/auth/Usera.js rename to lib/modules/auth/User.js index 50cbb024..026ce93d 100644 --- a/lib/modules/auth/Usera.js +++ b/lib/modules/auth/User.js @@ -1,104 +1,144 @@ +/** + * @flow + * User representation wrapper + */ import INTERNALS from './../../internals'; -/** - * @url https://firebase.google.com/docs/reference/js/firebase.User - */ +import type Auth from './'; + +type NativeUser = { + displayName?: string, + email?: string, + emailVerified?: boolean, + isAnonymous?: boolean, + phoneNumber?: string, + photoURL?: string, + providerData: UserInfo[], + providerId: string, + uid: string, +} + +type UserInfo = { + displayName?: string, + email?: string, + phoneNumber?: string, + photoURL?: string, + providerId: string, + uid: string, +} + export default class User { + _auth: Auth; + _user: NativeUser; + /** * - * @param authClass Instance of Authentication class + * @param auth Instance of Authentication class * @param user user result object from native */ - constructor(authClass, userObj) { - this._auth = authClass; - this._user = userObj; - } - - /** - * INTERNALS - */ - - /** - * Returns a user property or null if does not exist - * @param prop - * @returns {*} - * @private - */ - _valueOrNull(prop) { - if (!Object.hasOwnProperty.call(this._user, prop)) return null; - return this._user[prop]; - } - - /** - * Returns a user property or false if does not exist - * @param prop - * @returns {*} - * @private - */ - _valueOrFalse(prop) { - if (!Object.hasOwnProperty.call(this._user, prop)) return false; - return this._user[prop]; + constructor(auth: Auth, user: NativeUser) { + this._auth = auth; + this._user = user; } /** * PROPERTIES */ - get displayName(): String | null { - return this._valueOrNull('displayName'); + get displayName(): ?string { + return this._user.displayName || null; } - get email(): String | null { - return this._valueOrNull('email'); + get email(): ?string { + return this._user.email || null; } - get emailVerified(): Boolean { - return this._valueOrNull('emailVerified'); + get emailVerified(): boolean { + return this._user.emailVerified || false; } - get isAnonymous(): Boolean { - return this._valueOrFalse('isAnonymous'); + get isAnonymous(): boolean { + return this._user.isAnonymous || false; } - get phoneNumber(): String | null { - return this._valueOrNull('phoneNumber'); + get phoneNumber(): ?string { + return this._user.phoneNumber || null; } - get photoURL(): String | null { - return this._valueOrNull('photoURL'); + get photoURL(): ?string { + return this._user.photoURL || null; } - get providerId() { - return this._valueOrNull('providerId'); + get providerData(): Array { + return this._user.providerData; } - get uid(): String { - return this._valueOrNull('uid'); + get providerId(): string { + return this._user.providerId; + } + + get uid(): string { + return this._user.uid; } - // noinspection ReservedWordAsName /** * METHODS */ - toJSON() { - return Object.assign({}, this._user); - } - /** * Delete the current user * @return {Promise} */ - delete(): Promise { - return this._auth._interceptUserValue(this._auth._native.delete()); + delete(): Promise { + return this._auth + ._interceptUndefinedUserValue(this._auth._native.delete()); + } + + /** + * get the token of current user + * @return {Promise} + */ + getIdToken(forceRefresh: boolean = false): Promise { + return this._auth._native.getToken(forceRefresh); } /** * * @param credential */ - linkWithCredential(credential: CredentialType) { - return this._auth._interceptUserValue(this._auth._native.link(credential.providerId, credential.token, credential.secret)); + linkWithCredential(credential: AuthCredential): Promise { + return this._auth + ._interceptUserValue(this._auth._native.link(credential.providerId, credential.token, credential.secret)); + } + + /** + * Re-authenticate a user with a third-party authentication provider + * @return {Promise} A promise resolved upon completion + */ + reauthenticateWithCredential(credential: AuthCredential): Promise { + return this._auth + ._interceptUndefinedUserValue(this._auth._native.reauthenticate(credential.providerId, credential.token, credential.secret)); + } + + /** + * Reload the current user + * @return {Promise} + */ + reload(): Promise { + return this._auth + ._interceptUndefinedUserValue(this._auth._native.reload()); + } + + /** + * Send verification email to current user. + */ + sendEmailVerification(): Promise { + return this._auth + ._interceptUndefinedUserValue(this._auth._native.sendEmailVerification()); + } + + toJSON(): Object { + return Object.assign({}, this._user); } /** @@ -106,69 +146,19 @@ export default class User { * @param providerId * @return {Promise.|*} */ - unlink(providerId: string) { + unlink(providerId: string): Promise { return this._auth._interceptUserValue(this._auth._native.unlink(providerId)); } - /** - * Re-authenticate a user with a third-party authentication provider - * @return {Promise} A promise resolved upon completion - */ - reauthenticateWithCredential(credential: CredentialType) { - return this._auth._interceptUserValue(this._auth._native.reauthenticate(credential.providerId, credential.token, credential.secret)); - } - - /** - * Reload the current user - * @return {Promise} - */ - reload(): Promise { - return this._auth._interceptUserValue(this._auth._native.reload()); - } - - /** - * get the token of current user - * @deprecated Deprecated getToken in favor of getIdToken. - * @return {Promise} - */ - getToken(forceRefresh: Boolean = false): Promise { - console.warn('Deprecated firebase.User.prototype.getToken in favor of firebase.User.prototype.getIdToken.'); - return this._auth._native.getToken(forceRefresh); - } - - /** - * get the token of current user - * @return {Promise} - */ - getIdToken(forceRefresh: Boolean = false): Promise { - return this._auth._native.getToken(forceRefresh); - } - - /** - * - * @returns {Array} - */ - get providerData(): Array { - return this._valueOrNull('providerData') || []; - } - /** * Update the current user's email * * @param {string} email The user's _new_ email * @return {Promise} A promise resolved upon completion */ - updateEmail(email: string): Promise { - return this._auth._interceptUserValue(this._auth._native.updateEmail(email)); - } - - /** - * Update the current user's profile - * @param {Object} updates An object containing the keys listed [here](https://firebase.google.com/docs/auth/ios/manage-users#update_a_users_profile) - * @return {Promise} - */ - updateProfile(updates: Object = {}): Promise { - return this._auth._interceptUserValue(this._auth._native.updateProfile(updates)); + updateEmail(email: string): Promise { + return this._auth + ._interceptUndefinedUserValue(this._auth._native.updateEmail(email)); } /** @@ -176,15 +166,29 @@ export default class User { * @param {string} password the new password * @return {Promise} */ - updatePassword(password: string): Promise { - return this._auth._interceptUserValue(this._auth._native.updatePassword(password)); + updatePassword(password: string): Promise { + return this._auth + ._interceptUndefinedUserValue(this._auth._native.updatePassword(password)); } /** - * Send verification email to current user. + * Update the current user's profile + * @param {Object} updates An object containing the keys listed [here](https://firebase.google.com/docs/auth/ios/manage-users#update_a_users_profile) + * @return {Promise} */ - sendEmailVerification(): Promise { - return this._auth._interceptUserValue(this._auth._native.sendEmailVerification()); + updateProfile(updates: Object = {}): Promise { + return this._auth + ._interceptUndefinedUserValue(this._auth._native.updateProfile(updates)); + } + + /** + * get the token of current user + * @deprecated Deprecated getToken in favor of getIdToken. + * @return {Promise} + */ + getToken(forceRefresh: boolean = false): Promise { + console.warn('Deprecated firebase.User.prototype.getToken in favor of firebase.User.prototype.getIdToken.'); + return this._auth._native.getToken(forceRefresh); } /** @@ -223,7 +227,7 @@ export default class User { throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('User', 'updatePhoneNumber')); } - get refreshToken() { + get refreshToken(): string { throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('User', 'refreshToken')); } } diff --git a/lib/modules/auth/index.js b/lib/modules/auth/index.js index 378a23aa..fcd42b59 100644 --- a/lib/modules/auth/index.js +++ b/lib/modules/auth/index.js @@ -1,5 +1,8 @@ -// @flow -import User from './user'; +/** + * @flow + * Auth representation wrapper + */ +import User from './User'; import ModuleBase from './../../utils/ModuleBase'; import INTERNALS from './../../internals'; import ConfirmationResult from './ConfirmationResult'; @@ -14,16 +17,16 @@ import FacebookAuthProvider from './providers/FacebookAuthProvider'; import PhoneAuthListener from './PhoneAuthListener'; +import type FirebaseApp from '../../firebase-app'; + export default class Auth extends ModuleBase { static _NAMESPACE = 'auth'; static _NATIVE_MODULE = 'RNFirebaseAuth'; + _authResult: AuthResult | null; _user: User | null; - _native: Object; - _getAppEventName: Function; - _authResult: AuthResultType | null; - constructor(firebaseApp: Object, options: Object = {}) { + constructor(firebaseApp: FirebaseApp, options: Object = {}) { super(firebaseApp, options, true); this._user = null; this._authResult = null; @@ -31,21 +34,21 @@ export default class Auth extends ModuleBase { this.addListener( // sub to internal native event - this fans out to // public event name: onAuthStateChanged - this._getAppEventName('auth_state_changed'), + super._getAppEventName('auth_state_changed'), this._onInternalAuthStateChanged.bind(this), ); this.addListener( // sub to internal native event - this fans out to // public events based on event.type - this._getAppEventName('phone_auth_state_changed'), + super._getAppEventName('phone_auth_state_changed'), this._onInternalPhoneAuthStateChanged.bind(this), ); this.addListener( // sub to internal native event - this fans out to // public event name: onIdTokenChanged - this._getAppEventName('auth_id_token_changed'), + super._getAppEventName('auth_id_token_changed'), this._onInternalIdTokenChanged.bind(this), ); @@ -63,7 +66,7 @@ export default class Auth extends ModuleBase { this.emit(eventKey, event.state); } - _setAuthState(auth: AuthResultType) { + _setAuthState(auth: AuthResult) { this._authResult = auth; this._user = auth && auth.user ? new User(this, auth.user) : null; this.emit(this._getAppEventName('onUserChanged'), this._user); @@ -74,7 +77,7 @@ export default class Auth extends ModuleBase { * @param auth * @private */ - _onInternalAuthStateChanged(auth: AuthResultType) { + _onInternalAuthStateChanged(auth: AuthResult) { this._setAuthState(auth); this.emit(this._getAppEventName('onAuthStateChanged'), this._user); } @@ -85,7 +88,7 @@ export default class Auth extends ModuleBase { * @param emit * @private */ - _onInternalIdTokenChanged(auth: AuthResultType) { + _onInternalIdTokenChanged(auth: AuthResult) { this._setAuthState(auth); this.emit(this._getAppEventName('onIdTokenChanged'), this._user); } @@ -97,8 +100,8 @@ export default class Auth extends ModuleBase { * @returns {Promise.<*>} * @private */ - _interceptUserValue(promise) { - return promise.then((result) => { + _interceptUserValue(promise: Promise): Promise { + return promise.then((result: AuthResult) => { if (!result) this._setAuthState(null); else if (result.user) this._setAuthState(result); else if (result.uid) this._setAuthState({ authenticated: true, user: result }); @@ -106,6 +109,11 @@ export default class Auth extends ModuleBase { }); } + _interceptUndefinedUserValue(promise: Promise): Promise { + return this._interceptUserValue(promise) + .then(() => {}); + } + /* * WEB API */ @@ -174,15 +182,15 @@ export default class Auth extends ModuleBase { * Sign the current user out * @return {Promise} */ - signOut(): Promise { - return this._interceptUserValue(this._native.signOut()); + signOut(): Promise { + return this._interceptUndefinedUserValue(this._native.signOut()); } /** * Sign a user in anonymously * @return {Promise} A promise resolved upon completion */ - signInAnonymously(): Promise { + signInAnonymously(): Promise { return this._interceptUserValue(this._native.signInAnonymously()); } @@ -192,7 +200,7 @@ export default class Auth extends ModuleBase { * @param {string} password The user's password * @return {Promise} A promise indicating the completion */ - createUserWithEmailAndPassword(email: string, password: string): Promise { + createUserWithEmailAndPassword(email: string, password: string): Promise { return this._interceptUserValue(this._native.createUserWithEmailAndPassword(email, password)); } @@ -202,7 +210,7 @@ export default class Auth extends ModuleBase { * @param {string} password The user's password * @return {Promise} A promise that is resolved upon completion */ - signInWithEmailAndPassword(email: string, password: string): Promise { + signInWithEmailAndPassword(email: string, password: string): Promise { return this._interceptUserValue(this._native.signInWithEmailAndPassword(email, password)); } @@ -211,7 +219,7 @@ export default class Auth extends ModuleBase { * @param {string} customToken A self-signed custom auth token. * @return {Promise} A promise resolved upon completion */ - signInWithCustomToken(customToken: string): Promise { + signInWithCustomToken(customToken: string): Promise { return this._interceptUserValue(this._native.signInWithCustomToken(customToken)); } @@ -219,7 +227,7 @@ export default class Auth extends ModuleBase { * Sign the user in with a third-party authentication provider * @return {Promise} A promise resolved upon completion */ - signInWithCredential(credential: CredentialType): Promise { + signInWithCredential(credential: AuthCredential): Promise { return this._interceptUserValue( this._native.signInWithCredential( credential.providerId, credential.token, credential.secret, @@ -231,7 +239,7 @@ export default class Auth extends ModuleBase { * Asynchronously signs in using a phone number. * */ - signInWithPhoneNumber(phoneNumber: string): Promise { + signInWithPhoneNumber(phoneNumber: string): Promise { return this._native.signInWithPhoneNumber(phoneNumber).then((result) => { return new ConfirmationResult(this, result.verificationId); }); @@ -254,7 +262,7 @@ export default class Auth extends ModuleBase { * Send reset password instructions via email * @param {string} email The email to send password reset instructions */ - sendPasswordResetEmail(email: string): Promise { + sendPasswordResetEmail(email: string): Promise { return this._native.sendPasswordResetEmail(email); } @@ -266,7 +274,7 @@ export default class Auth extends ModuleBase { * @param newPassword * @return {Promise.} */ - confirmPasswordReset(code: string, newPassword: string): Promise { + confirmPasswordReset(code: string, newPassword: string): Promise { return this._native.confirmPasswordReset(code, newPassword); } @@ -277,7 +285,7 @@ export default class Auth extends ModuleBase { * @param code * @return {Promise.} */ - applyActionCode(code: string): Promise { + applyActionCode(code: string): Promise { return this._native.applyActionCode(code); } @@ -288,7 +296,7 @@ export default class Auth extends ModuleBase { * @param code * @return {Promise.|Promise} */ - checkActionCode(code: string): Promise { + checkActionCode(code: string): Promise { return this._native.checkActionCode(code); } @@ -296,7 +304,7 @@ export default class Auth extends ModuleBase { * Get the currently signed in user * @return {Promise} */ - getCurrentUser(): Promise { + getCurrentUser(): Promise { return this._interceptUserValue(this._native.getCurrentUser()); } diff --git a/lib/modules/auth/providers/EmailAuthProvider.js b/lib/modules/auth/providers/EmailAuthProvider.js index d4175aba..b995687f 100644 --- a/lib/modules/auth/providers/EmailAuthProvider.js +++ b/lib/modules/auth/providers/EmailAuthProvider.js @@ -1,3 +1,7 @@ +/** + * @flow + * EmailAuthProvider representation wrapper + */ const providerId = 'password'; export default class EmailAuthProvider { @@ -5,11 +9,11 @@ export default class EmailAuthProvider { throw new Error('`new EmailAuthProvider()` is not supported on the native Firebase SDKs.'); } - static get PROVIDER_ID() { + static get PROVIDER_ID(): string { return providerId; } - static credential(email, password) { + static credential(email: string, password: string): AuthCredential { return { token: email, secret: password, diff --git a/lib/modules/auth/providers/FacebookAuthProvider.js b/lib/modules/auth/providers/FacebookAuthProvider.js index c8abbc10..b60bf027 100644 --- a/lib/modules/auth/providers/FacebookAuthProvider.js +++ b/lib/modules/auth/providers/FacebookAuthProvider.js @@ -1,3 +1,7 @@ +/** + * @flow + * FacebookAuthProvider representation wrapper + */ const providerId = 'facebook.com'; export default class FacebookAuthProvider { @@ -5,11 +9,11 @@ export default class FacebookAuthProvider { throw new Error('`new FacebookAuthProvider()` is not supported on the native Firebase SDKs.'); } - static get PROVIDER_ID() { + static get PROVIDER_ID(): string { return providerId; } - static credential(token) { + static credential(token: string): AuthCredential { return { token, secret: '', diff --git a/lib/modules/auth/providers/GithubAuthProvider.js b/lib/modules/auth/providers/GithubAuthProvider.js index fbd84272..4500ce40 100644 --- a/lib/modules/auth/providers/GithubAuthProvider.js +++ b/lib/modules/auth/providers/GithubAuthProvider.js @@ -1,3 +1,7 @@ +/** + * @flow + * GithubAuthProvider representation wrapper + */ const providerId = 'github.com'; export default class GithubAuthProvider { @@ -5,11 +9,11 @@ export default class GithubAuthProvider { throw new Error('`new GithubAuthProvider()` is not supported on the native Firebase SDKs.'); } - static get PROVIDER_ID() { + static get PROVIDER_ID(): string { return providerId; } - static credential(token) { + static credential(token: string): AuthCredential { return { token, secret: '', diff --git a/lib/modules/auth/providers/GoogleAuthProvider.js b/lib/modules/auth/providers/GoogleAuthProvider.js index eda9f241..717aa0ce 100644 --- a/lib/modules/auth/providers/GoogleAuthProvider.js +++ b/lib/modules/auth/providers/GoogleAuthProvider.js @@ -1,3 +1,7 @@ +/** + * @flow + * EmailAuthProvider representation wrapper + */ const providerId = 'google.com'; export default class GoogleAuthProvider { @@ -5,11 +9,11 @@ export default class GoogleAuthProvider { throw new Error('`new GoogleAuthProvider()` is not supported on the native Firebase SDKs.'); } - static get PROVIDER_ID() { + static get PROVIDER_ID(): string { return providerId; } - static credential(token, secret) { + static credential(token: string, secret: string): AuthCredential { return { token, secret, diff --git a/lib/modules/auth/providers/PhoneAuthProvider.js b/lib/modules/auth/providers/PhoneAuthProvider.js index 5186f009..6ac1cc57 100644 --- a/lib/modules/auth/providers/PhoneAuthProvider.js +++ b/lib/modules/auth/providers/PhoneAuthProvider.js @@ -1,3 +1,7 @@ +/** + * @flow + * PhoneAuthProvider representation wrapper + */ const providerId = 'phone'; export default class PhoneAuthProvider { @@ -5,11 +9,11 @@ export default class PhoneAuthProvider { throw new Error('`new PhoneAuthProvider()` is not supported on the native Firebase SDKs.'); } - static get PROVIDER_ID() { + static get PROVIDER_ID(): string { return providerId; } - static credential(verificationId, code) { + static credential(verificationId: string, code: string): AuthCredential { return { token: verificationId, secret: code, diff --git a/lib/modules/auth/providers/TwitterAuthProvider.js b/lib/modules/auth/providers/TwitterAuthProvider.js index 15c0a2f6..7f6cf902 100644 --- a/lib/modules/auth/providers/TwitterAuthProvider.js +++ b/lib/modules/auth/providers/TwitterAuthProvider.js @@ -1,3 +1,7 @@ +/** + * @flow + * TwitterAuthProvider representation wrapper + */ const providerId = 'twitter.com'; export default class TwitterAuthProvider { @@ -5,11 +9,11 @@ export default class TwitterAuthProvider { throw new Error('`new TwitterAuthProvider()` is not supported on the native Firebase SDKs.'); } - static get PROVIDER_ID() { + static get PROVIDER_ID(): string { return providerId; } - static credential(token, secret) { + static credential(token: string, secret: string): AuthCredential { return { token, secret, diff --git a/lib/modules/firestore/CollectionReference.js b/lib/modules/firestore/CollectionReference.js index 9c46eda2..6a906be9 100644 --- a/lib/modules/firestore/CollectionReference.js +++ b/lib/modules/firestore/CollectionReference.js @@ -3,7 +3,7 @@ * CollectionReference representation wrapper */ import DocumentReference from './DocumentReference'; -import Query, { type Direction, type Operator } from './Query'; +import Query from './Query'; import { firestoreAutoId } from '../../utils'; import type Firestore from './'; @@ -75,7 +75,7 @@ export default class CollectionReference { return this._query.onSnapshot(onNext, onError); } - orderBy(fieldPath: string, directionStr?: Direction): Query { + orderBy(fieldPath: string, directionStr?: FirestoreQueryDirection): Query { return this._query.orderBy(fieldPath, directionStr); } @@ -87,7 +87,7 @@ export default class CollectionReference { return this._query.startAt(fieldValues); } - where(fieldPath: string, opStr: Operator, value: any): Query { + where(fieldPath: string, opStr: FirestoreQueryOperator, value: any): Query { return this._query.where(fieldPath, opStr, value); } } diff --git a/lib/modules/firestore/DocumentChange.js b/lib/modules/firestore/DocumentChange.js index b712aa7a..ffcda39d 100644 --- a/lib/modules/firestore/DocumentChange.js +++ b/lib/modules/firestore/DocumentChange.js @@ -2,18 +2,10 @@ * @flow * DocumentChange representation wrapper */ -import DocumentSnapshot, { type DocumentSnapshotNativeData } from './DocumentSnapshot'; +import DocumentSnapshot from './DocumentSnapshot'; import type Firestore from './'; - -export type DocumentChangeNativeData = { - document: DocumentSnapshotNativeData, - newIndex: number, - oldIndex: number, - type: string, -} - /** * @class DocumentChange */ @@ -23,7 +15,7 @@ export default class DocumentChange { _oldIndex: number; _type: string; - constructor(firestore: Firestore, nativeData: DocumentChangeNativeData) { + constructor(firestore: Firestore, nativeData: FirestoreNativeDocumentChange) { this._document = new DocumentSnapshot(firestore, nativeData.document); this._newIndex = nativeData.newIndex; this._oldIndex = nativeData.oldIndex; diff --git a/lib/modules/firestore/DocumentReference.js b/lib/modules/firestore/DocumentReference.js index b6a703ed..aff4d304 100644 --- a/lib/modules/firestore/DocumentReference.js +++ b/lib/modules/firestore/DocumentReference.js @@ -3,17 +3,13 @@ * DocumentReference representation wrapper */ import CollectionReference from './CollectionReference'; -import DocumentSnapshot, { type DocumentSnapshotNativeData } from './DocumentSnapshot'; +import DocumentSnapshot from './DocumentSnapshot'; import { buildNativeMap } from './utils/serialize'; import { firestoreAutoId, isFunction, isObject, isString } from '../../utils'; import type Firestore from './'; import type Path from './Path'; -export type WriteOptions = { - merge?: boolean, -} - type DocumentListenOptions = { includeMetadataChanges: boolean, } @@ -133,7 +129,7 @@ export default class DocumentReference { } const listenerId = firestoreAutoId(); - const listener = (nativeDocumentSnapshot: DocumentSnapshotNativeData) => { + const listener = (nativeDocumentSnapshot: FirestoreNativeDocumentSnapshot) => { const documentSnapshot = new DocumentSnapshot(this.firestore, nativeDocumentSnapshot); observer.next(documentSnapshot); }; @@ -160,7 +156,7 @@ export default class DocumentReference { return this._offDocumentSnapshot.bind(this, listenerId, listener); } - set(data: Object, writeOptions?: WriteOptions): Promise { + set(data: Object, writeOptions?: FirestoreWriteOptions): Promise { const nativeData = buildNativeMap(data); return this._firestore._native .documentSet(this.path, nativeData, writeOptions); diff --git a/lib/modules/firestore/DocumentSnapshot.js b/lib/modules/firestore/DocumentSnapshot.js index 35899c47..ab2bb378 100644 --- a/lib/modules/firestore/DocumentSnapshot.js +++ b/lib/modules/firestore/DocumentSnapshot.js @@ -4,30 +4,19 @@ */ import DocumentReference from './DocumentReference'; import Path from './Path'; -import { parseNativeMap, type TypeMap } from './utils/serialize'; +import { parseNativeMap } from './utils/serialize'; import type Firestore from './'; -export type SnapshotMetadata = { - fromCache: boolean, - hasPendingWrites: boolean, -} - -export type DocumentSnapshotNativeData = { - data: { [string]: TypeMap }, - metadata: SnapshotMetadata, - path: string, -} - /** * @class DocumentSnapshot */ export default class DocumentSnapshot { _data: Object | void; - _metadata: SnapshotMetadata; + _metadata: FirestoreSnapshotMetadata; _ref: DocumentReference; - constructor(firestore: Firestore, nativeData: DocumentSnapshotNativeData) { + constructor(firestore: Firestore, nativeData: FirestoreNativeDocumentSnapshot) { this._data = parseNativeMap(firestore, nativeData.data); this._metadata = nativeData.metadata; this._ref = new DocumentReference(firestore, Path.fromName(nativeData.path)); @@ -41,7 +30,7 @@ export default class DocumentSnapshot { return this._ref.id; } - get metadata(): SnapshotMetadata { + get metadata(): FirestoreSnapshotMetadata { return this._metadata; } diff --git a/lib/modules/firestore/Query.js b/lib/modules/firestore/Query.js index 26bd0b22..81561b47 100644 --- a/lib/modules/firestore/Query.js +++ b/lib/modules/firestore/Query.js @@ -10,14 +10,14 @@ import { firestoreAutoId, isFunction, isObject } from '../../utils'; import type Firestore from './'; import type Path from './Path'; -const DIRECTIONS = { +const DIRECTIONS: { [FirestoreQueryDirection]: string } = { ASC: 'ASCENDING', asc: 'ASCENDING', DESC: 'DESCENDING', desc: 'DESCENDING', }; -const OPERATORS = { +const OPERATORS: { [FirestoreQueryOperator]: string } = { '=': 'EQUAL', '==': 'EQUAL', '>': 'GREATER_THAN', @@ -26,7 +26,6 @@ const OPERATORS = { '<=': 'LESS_THAN_OR_EQUAL', }; -export type Direction = 'DESC' | 'desc' | 'ASC' | 'asc'; type FieldFilter = { fieldPath: string, operator: string, @@ -45,7 +44,6 @@ type QueryOptions = { startAfter?: any[], startAt?: any[], } -export type Operator = '<' | '<=' | '=' | '==' | '>' | '>='; type QueryListenOptions = { includeDocumentMetadataChanges: boolean, includeQueryMetadataChanges: boolean, @@ -234,7 +232,7 @@ export default class Query { return this._offCollectionSnapshot.bind(this, listenerId, listener); } - orderBy(fieldPath: string, directionStr?: Direction = 'asc'): Query { + orderBy(fieldPath: string, directionStr?: FirestoreQueryDirection = 'asc'): Query { // TODO: Validation // validate.isFieldPath('fieldPath', fieldPath); // validate.isOptionalFieldOrder('directionStr', directionStr); @@ -288,7 +286,7 @@ export default class Query { ); } - where(fieldPath: string, opStr: Operator, value: any): Query { + where(fieldPath: string, opStr: FirestoreQueryOperator, value: any): Query { // TODO: Validation // validate.isFieldPath('fieldPath', fieldPath); // validate.isFieldFilter('fieldFilter', opStr, value); diff --git a/lib/modules/firestore/QuerySnapshot.js b/lib/modules/firestore/QuerySnapshot.js index c7759b22..659815aa 100644 --- a/lib/modules/firestore/QuerySnapshot.js +++ b/lib/modules/firestore/QuerySnapshot.js @@ -2,16 +2,16 @@ * @flow * QuerySnapshot representation wrapper */ -import DocumentChange, { type DocumentChangeNativeData } from './DocumentChange'; -import DocumentSnapshot, { type DocumentSnapshotNativeData, type SnapshotMetadata } from './DocumentSnapshot'; +import DocumentChange from './DocumentChange'; +import DocumentSnapshot from './DocumentSnapshot'; import type Firestore from './'; import type Query from './Query'; type QuerySnapshotNativeData = { - changes: DocumentChangeNativeData[], - documents: DocumentSnapshotNativeData[], - metadata: SnapshotMetadata, + changes: FirestoreNativeDocumentChange[], + documents: FirestoreNativeDocumentSnapshot[], + metadata: FirestoreSnapshotMetadata, } /** @@ -20,7 +20,7 @@ type QuerySnapshotNativeData = { export default class QuerySnapshot { _changes: DocumentChange[]; _docs: DocumentSnapshot[]; - _metadata: SnapshotMetadata; + _metadata: FirestoreSnapshotMetadata; _query: Query; constructor(firestore: Firestore, query: Query, nativeData: QuerySnapshotNativeData) { @@ -42,7 +42,7 @@ export default class QuerySnapshot { return this._docs.length === 0; } - get metadata(): SnapshotMetadata { + get metadata(): FirestoreSnapshotMetadata { return this._metadata; } diff --git a/lib/modules/firestore/WriteBatch.js b/lib/modules/firestore/WriteBatch.js index 70771124..77318c3c 100644 --- a/lib/modules/firestore/WriteBatch.js +++ b/lib/modules/firestore/WriteBatch.js @@ -5,7 +5,7 @@ import { buildNativeMap } from './utils/serialize'; import { isObject, isString } from '../../utils'; -import type DocumentReference, { WriteOptions } from './DocumentReference'; +import type DocumentReference from './DocumentReference'; import type Firestore from './'; type DocumentWrite = { @@ -44,7 +44,7 @@ export default class WriteBatch { return this; } - set(docRef: DocumentReference, data: Object, writeOptions?: WriteOptions) { + set(docRef: DocumentReference, data: Object, writeOptions?: FirestoreWriteOptions) { // TODO: Validation // validate.isDocumentReference('docRef', docRef); // validate.isDocument('data', data); diff --git a/lib/modules/firestore/utils/serialize.js b/lib/modules/firestore/utils/serialize.js index 4657711c..74fd2697 100644 --- a/lib/modules/firestore/utils/serialize.js +++ b/lib/modules/firestore/utils/serialize.js @@ -10,18 +10,13 @@ import { typeOf } from '../../../utils'; import type Firestore from '../'; -export type TypeMap = { - type: 'array' | 'boolean' | 'date' | 'fieldvalue' | 'geopoint' | 'null' | 'number' | 'object' | 'reference' | 'string', - value: any, -} - /* * Functions that build up the data needed to represent * the different types available within Firestore * for transmission to the native side */ -export const buildNativeMap = (data: Object): { [string]: TypeMap } => { +export const buildNativeMap = (data: Object): { [string]: FirestoreTypeMap } => { const nativeData = {}; if (data) { Object.keys(data).forEach((key) => { @@ -34,7 +29,7 @@ export const buildNativeMap = (data: Object): { [string]: TypeMap } => { return nativeData; }; -export const buildNativeArray = (array: Object[]): TypeMap[] => { +export const buildNativeArray = (array: Object[]): FirestoreTypeMap[] => { const nativeArray = []; if (array) { array.forEach((value) => { @@ -47,7 +42,7 @@ export const buildNativeArray = (array: Object[]): TypeMap[] => { return nativeArray; }; -export const buildTypeMap = (value: any): TypeMap | null => { +export const buildTypeMap = (value: any): FirestoreTypeMap | null => { const type = typeOf(value); if (value === null || value === undefined) { return { @@ -108,7 +103,7 @@ export const buildTypeMap = (value: any): TypeMap | null => { * side and converts to the correct Firestore JS types */ -export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: TypeMap }): Object | void => { +export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: FirestoreTypeMap }): Object | void => { let data; if (nativeData) { data = {}; @@ -119,7 +114,7 @@ export const parseNativeMap = (firestore: Firestore, nativeData: { [string]: Typ return data; }; -const parseNativeArray = (firestore: Firestore, nativeArray: TypeMap[]): any[] => { +const parseNativeArray = (firestore: Firestore, nativeArray: FirestoreTypeMap[]): any[] => { const array = []; if (nativeArray) { nativeArray.forEach((typeMap) => { @@ -129,7 +124,7 @@ const parseNativeArray = (firestore: Firestore, nativeArray: TypeMap[]): any[] = return array; }; -const parseTypeMap = (firestore: Firestore, typeMap: TypeMap): any => { +const parseTypeMap = (firestore: Firestore, typeMap: FirestoreTypeMap): any => { const { type, value } = typeMap; if (type === 'null') { return null;