Merge branch 'firestore-transactions' of https://github.com/invertase/react-native-firebase into firestore-transactions

This commit is contained in:
Salakar 2018-02-15 15:35:33 +00:00
commit d00fa4faa3
14 changed files with 106086 additions and 262 deletions

View File

@ -5,7 +5,7 @@ The issue list of this repo is exclusively for bug reports.
1) For feature requests, please use our Canny board: https://react-native-firebase.canny.io/feature-requests
2) For questions and support please use our Discord chat: https://discord.gg/t6bdqMs or Stack Overflow: https://stackoverflow.com/questions/tagged/react-native-firebase
2) For questions and support please use our Discord chat: https://discord.gg/C9aK28N or Stack Overflow: https://stackoverflow.com/questions/tagged/react-native-firebase
3) If this is a setup issue then please make sure you've correctly followed the setup guides, most setup issues such as 'duplicate dex files', 'default app has not been initialized' etc are all down to an incorrect setup as the guides haven't been correctly followed.
-->

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
coverage
node_modules
npm-debug.log
*.DS_Store

View File

@ -1,4 +1,7 @@
node_modules
coverage.android.json
coverage.ios.json
coverage
npm-debug.log
*.DS_Store
.github

View File

@ -1,4 +1,4 @@
Copyright (c) 2017 Invertase Limited <oss@invertase.io>
Copyright (c) 2018 Invertase Limited <oss@invertase.io>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this library except in compliance with the License.

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="#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="https://discord.gg/t6bdqMs"><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/badge/chat-on%20discord-7289da.svg?style=flat-square" 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>
</p>
@ -77,7 +77,7 @@ To check out our latest docs, visit [rnfirebase.io](https://rnfirebase.io)
## Questions
For questions and support please use our [Discord chat](https://discord.gg/t6bdqMs) or [Stack Overflow](https://stackoverflow.com/questions/tagged/react-native-firebase). The issue list of this repo is **exclusively** for bug reports.
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.
## Issues

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
# Copy firebase lib into tests directory
mkdir tests/firebase
cp -R lib/* tests/firebase
# Install /tests npm packages
cd tests && npm install

52792
coverage.android.json Normal file

File diff suppressed because it is too large Load Diff

52792
coverage.ios.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,179 @@
/**
* @flow
* Firestore Transaction representation wrapper
*/
import { mergeFieldPathData } from './utils';
import { buildNativeMap } from './utils/serialize';
import type Firestore from './';
import type { TransactionMeta } from './TransactionHandler';
import type DocumentReference from './DocumentReference';
import type DocumentSnapshot from './DocumentSnapshot';
import { isObject, isString } from '../../utils';
import FieldPath from './FieldPath';
import { getNativeModule } from '../../utils/native';
type Command = {
type: 'set' | 'update' | 'delete',
path: string,
data: ?{ [string]: any },
options: ?{ merge: boolean },
};
type SetOptions = {
merge: boolean,
};
/**
* @class Transaction
*/
export default class Transaction {
_pendingResult: ?any;
_firestore: Firestore;
_meta: TransactionMeta;
_commandBuffer: Array<Command>;
constructor(firestore: Firestore, meta: TransactionMeta) {
this._meta = meta;
this._commandBuffer = [];
this._firestore = firestore;
this._pendingResult = undefined;
}
/**
* -------------
* INTERNAL API
* -------------
*/
/**
* Clears the command buffer and any pending result in prep for
* the next transaction iteration attempt.
*
* @private
*/
_prepare() {
this._commandBuffer = [];
this._pendingResult = undefined;
}
/**
* -------------
* PUBLIC API
* -------------
*/
/**
* Reads the document referenced by the provided DocumentReference.
*
* @param documentRef DocumentReference A reference to the document to be retrieved. Value must not be null.
*
* @returns Promise<DocumentSnapshot>
*/
get(documentRef: DocumentReference): Promise<DocumentSnapshot> {
// todo validate doc ref
return getNativeModule(this._firestore).transactionGetDocument(
this._meta.id,
documentRef.path
);
}
/**
* Writes to the document referred to by the provided DocumentReference.
* If the document does not exist yet, it will be created. If you pass options,
* the provided data can be merged into the existing document.
*
* @param documentRef DocumentReference A reference to the document to be created. Value must not be null.
* @param data Object An object of the fields and values for the document.
* @param options SetOptions An object to configure the set behavior.
* Pass {merge: true} to only replace the values specified in the data argument.
* Fields omitted will remain untouched.
*
* @returns {Transaction}
*/
set(
documentRef: DocumentReference,
data: Object,
options?: SetOptions
): Transaction {
// todo validate doc ref
// todo validate data is object
this._commandBuffer.push({
type: 'set',
path: documentRef.path,
data: buildNativeMap(data),
options,
});
return this;
}
/**
* Updates fields in the document referred to by this DocumentReference.
* The update will fail if applied to a document that does not exist. Nested
* fields can be updated by providing dot-separated field path strings or by providing FieldPath objects.
*
* @param documentRef DocumentReference A reference to the document to be updated. Value must not be null.
* @param args any Either an object containing all of the fields and values to update,
* or a series of arguments alternating between fields (as string or FieldPath
* objects) and values.
*
* @returns {Transaction}
*/
update(documentRef: DocumentReference, ...args: Array<any>): Transaction {
// todo validate doc ref
let data = {};
if (args.length === 1) {
if (!isObject(args[0])) {
throw new Error(
'Transaction.update failed: If using a single data argument, it must be an object.'
);
}
[data] = args;
} else if (args.length % 2 === 1) {
throw new Error(
'Transaction.update failed: Must have either a single object data argument, or equal numbers of data key/value pairs.'
);
} else {
for (let i = 0; i < args.length; i += 2) {
const key = args[i];
const value = args[i + 1];
if (isString(key)) {
data[key] = value;
} else if (key instanceof FieldPath) {
data = mergeFieldPathData(data, key._segments, value);
} else {
throw new Error(
`Transaction.update failed: Argument at index ${i} must be a string or FieldPath`
);
}
}
}
this._commandBuffer.push({
type: 'update',
path: documentRef.path,
data: buildNativeMap(data),
});
return this;
}
/**
* Deletes the document referred to by the provided DocumentReference.
*
* @param documentRef DocumentReference A reference to the document to be deleted. Value must not be null.
*
* @returns {Transaction}
*/
delete(documentRef: DocumentReference): Transaction {
// todo validate doc ref
this._commandBuffer.push({
type: 'delete',
path: documentRef.path,
});
return this;
}
}

View File

@ -0,0 +1,231 @@
/**
* @flow
* Firestore Transaction representation wrapper
*/
import { getAppEventName, SharedEventEmitter } from '../../utils/events';
import { getLogger } from '../../utils/log';
import { getNativeModule } from '../../utils/native';
import Transaction from './Transaction';
import type Firestore from './';
let transactionId = 0;
/**
* Uses the push id generator to create a transaction id
* @returns {number}
* @private
*/
const generateTransactionId = (): number => transactionId++;
export type TransactionMeta = {
id: number,
stack: Array<string>,
reject: null | Function,
resolve: null | Function,
transaction: Transaction,
updateFunction: (transaction: Transaction) => Promise<any>,
};
type TransactionEvent = {
id: number,
type: 'update' | 'error' | 'complete',
error: ?{ code: string, message: string },
};
/**
* @class TransactionHandler
*/
export default class TransactionHandler {
_firestore: Firestore;
_transactionListener: Function;
_pending: { [number]: TransactionMeta };
constructor(firestore: Firestore) {
this._pending = {};
this._firestore = firestore;
this._transactionListener = SharedEventEmitter.addListener(
getAppEventName(this._firestore, 'firestore_transaction_event'),
this._handleTransactionEvent.bind(this)
);
}
/**
* -------------
* INTERNAL API
* -------------
*/
/**
* Add a new transaction and start it natively.
* @param updateFunction
*/
_add(
updateFunction: (transaction: Transaction) => Promise<any>
): Promise<any> {
const id = generateTransactionId();
const meta = {
id,
reject: null,
resolve: null,
updateFunction,
stack: new Error().stack.slice(1),
};
meta.transaction = new Transaction(this._firestore, meta);
this._pending[id] = meta;
// deferred promise
return new Promise((resolve, reject) => {
getNativeModule(this._firestore).transactionBegin(id);
meta.resolve = r => {
resolve(r);
this._remove(id);
};
meta.reject = e => {
reject(e);
this._remove(id);
};
});
}
/**
* Destroys a local instance of a transaction meta
*
* @param id
* @param pendingAbort Notify native that there's still an transaction in
* progress that needs aborting - this is to handle a JS side
* exception
* @private
*/
_remove(id, pendingAbort = false) {
// todo confirm pending arg no longer needed
getNativeModule(this._firestore).transactionDispose(id, pendingAbort);
// TODO may need delaying to next event loop
delete this._pending[id];
}
/**
* -------------
* EVENTS
* -------------
*/
/**
* Handles incoming native transaction events and distributes to correct
* internal handler by event.type
*
* @param event
* @returns {*}
* @private
*/
_handleTransactionEvent(event: TransactionEvent) {
switch (event.type) {
case 'update':
return this._handleUpdate(event);
case 'error':
return this._handleError(event);
case 'complete':
return this._handleComplete(event);
default:
getLogger(this._firestore).warn(
`Unknown transaction event type: '${event.type}'`,
event
);
return undefined;
}
}
/**
* Handles incoming native transaction update events
*
* @param event
* @private
*/
async _handleUpdate(event: TransactionEvent) {
const { id } = event;
// abort if no longer exists js side
if (!this._pending[id]) return this._remove(id);
const { updateFunction, transaction, reject } = this._pending[id];
// clear any saved state from previous transaction runs
transaction._prepare();
let finalError;
let updateFailed;
let pendingResult;
// run the users custom update functionality
try {
const possiblePromise = updateFunction(transaction);
// validate user has returned a promise in their update function
// TODO must it actually return a promise? Can't find any usages of it without one...
if (!possiblePromise || !possiblePromise.then) {
finalError = new Error(
'Update function for `firestore.runTransaction(updateFunction)` must return a Promise.'
);
} else {
pendingResult = await possiblePromise;
}
} catch (exception) {
updateFailed = true; // in case the user rejects with nothing
finalError = exception;
}
// reject the final promise and remove from native
if (updateFailed) {
return reject(finalError);
}
// capture the resolved result as we'll need this
// to resolve the runTransaction() promise when
// native emits that the transaction is final
transaction._pendingResult = pendingResult;
// send the buffered update/set/delete commands for native to process
return getNativeModule(this._firestore).transactionProcessUpdateResponse(
id,
transaction._commandBuffer
);
}
/**
* Handles incoming native transaction error events
*
* @param event
* @private
*/
_handleError(event: TransactionEvent) {
const { id, error } = event;
const meta = this._pending[id];
if (meta) {
const { code, message } = error;
// build a JS error and replace its stack
// with the captured one at start of transaction
// so it's actually relevant to the user
const errorWithStack = new Error(message);
errorWithStack.code = code;
errorWithStack.stack = meta.stack;
meta.reject(errorWithStack);
}
}
/**
* Handles incoming native transaction complete events
*
* @param event
* @private
*/
_handleComplete(event: TransactionEvent) {
const { id } = event;
const meta = this._pending[id];
if (meta) {
const pendingResult = meta.transaction._pendingResult;
meta.resolve(pendingResult);
}
}
}

View File

@ -13,6 +13,8 @@ import FieldValue from './FieldValue';
import GeoPoint from './GeoPoint';
import Path from './Path';
import WriteBatch from './WriteBatch';
import TransactionHandler from './TransactionHandler';
import Transaction from './Transaction';
import INTERNALS from '../../utils/internals';
import type DocumentSnapshot from './DocumentSnapshot';
@ -36,8 +38,9 @@ type DocumentSyncEvent = {
};
const NATIVE_EVENTS = [
'firestore_collection_sync_event',
'firestore_transaction_event',
'firestore_document_sync_event',
'firestore_collection_sync_event',
];
export const MODULE_NAME = 'RNFirebaseFirestore';
@ -48,6 +51,7 @@ export const NAMESPACE = 'firestore';
*/
export default class Firestore extends ModuleBase {
_referencePath: Path;
_transactionHandler: TransactionHandler;
constructor(app: App) {
super(app, {
@ -56,7 +60,9 @@ export default class Firestore extends ModuleBase {
multiApp: true,
namespace: NAMESPACE,
});
this._referencePath = new Path([]);
this._transactionHandler = new TransactionHandler(this);
SharedEventEmitter.addListener(
// sub to internal native event - this fans out to
@ -73,11 +79,23 @@ export default class Firestore extends ModuleBase {
);
}
/**
* -------------
* PUBLIC API
* -------------
*/
/**
* Creates a write batch, used for performing multiple writes as a single atomic operation.
*
* @returns {WriteBatch}
*/
batch(): WriteBatch {
return new WriteBatch(this);
}
/**
* Gets a CollectionReference instance that refers to the collection at the specified path.
*
* @param collectionPath
* @returns {CollectionReference}
@ -92,6 +110,7 @@ export default class Firestore extends ModuleBase {
}
/**
* Gets a DocumentReference instance that refers to the document at the specified path.
*
* @param documentPath
* @returns {DocumentReference}
@ -105,13 +124,27 @@ export default class Firestore extends ModuleBase {
return new DocumentReference(this, path);
}
enablePersistence(): Promise<void> {
throw new Error('Persistence is enabled by default on the Firestore SDKs');
/**
* Executes the given updateFunction and then attempts to commit the
* changes applied within the transaction. If any document read within
* the transaction has changed, Cloud Firestore retries the updateFunction.
*
* If it fails to commit after 5 attempts, the transaction fails.
*
* @param updateFunction
* @returns {void|Promise<any>}
*/
runTransaction(
updateFunction: (transaction: Transaction) => Promise<any>
): Promise<any> {
return this._transactionHandler._add(updateFunction);
}
runTransaction(): Promise<any> {
throw new Error('firebase.firestore().runTransaction() coming soon');
}
/**
* -------------
* UNSUPPORTED
* -------------
*/
setLogLevel(): void {
throw new Error(
@ -121,13 +154,45 @@ export default class Firestore extends ModuleBase {
)
);
}
enableNetwork(): void {
throw new Error(
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
'firestore',
'enableNetwork'
)
);
}
disableNetwork(): void {
throw new Error(
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
'firestore',
'disableNetwork'
)
);
}
/**
* -------------
* MISC
* -------------
*/
enablePersistence(): Promise<void> {
throw new Error('Persistence is enabled by default on the Firestore SDKs');
}
settings(): void {
throw new Error('firebase.firestore().settings() coming soon');
}
/**
* -------------
* INTERNALS
* -------------
*/
/**
* Internal collection sync listener
*
* @param event
* @private
*/
@ -147,6 +212,7 @@ export default class Firestore extends ModuleBase {
/**
* Internal document sync listener
*
* @param event
* @private
*/

View File

@ -1,236 +0,0 @@
PODS:
- BoringSSL (9.2):
- BoringSSL/Implementation (= 9.2)
- BoringSSL/Interface (= 9.2)
- BoringSSL/Implementation (9.2):
- BoringSSL/Interface (= 9.2)
- BoringSSL/Interface (9.2)
- Crashlytics (3.9.3):
- Fabric (~> 1.7.2)
- Fabric (1.7.2)
- Firebase/AdMob (4.8.1):
- Firebase/Core
- Google-Mobile-Ads-SDK (= 7.27.0)
- Firebase/Auth (4.8.1):
- Firebase/Core
- FirebaseAuth (= 4.4.2)
- Firebase/Core (4.8.1):
- FirebaseAnalytics (= 4.0.7)
- FirebaseCore (= 4.0.14)
- Firebase/Crash (4.8.1):
- Firebase/Core
- FirebaseCrash (= 2.0.2)
- Firebase/Database (4.8.1):
- Firebase/Core
- FirebaseDatabase (= 4.1.4)
- Firebase/DynamicLinks (4.8.1):
- Firebase/Core
- FirebaseDynamicLinks (= 2.3.2)
- Firebase/Firestore (4.8.1):
- Firebase/Core
- FirebaseFirestore (= 0.10.0)
- Firebase/Messaging (4.8.1):
- Firebase/Core
- FirebaseMessaging (= 2.0.8)
- Firebase/Performance (4.8.1):
- Firebase/Core
- FirebasePerformance (= 1.1.1)
- Firebase/RemoteConfig (4.8.1):
- Firebase/Core
- FirebaseRemoteConfig (= 2.1.1)
- Firebase/Storage (4.8.1):
- Firebase/Core
- FirebaseStorage (= 2.1.2)
- FirebaseABTesting (1.0.0):
- FirebaseCore (~> 4.0)
- Protobuf (~> 3.1)
- FirebaseAnalytics (4.0.7):
- FirebaseCore (~> 4.0)
- FirebaseInstanceID (~> 2.0)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- nanopb (~> 0.3)
- FirebaseAuth (4.4.2):
- FirebaseAnalytics (~> 4.0)
- GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)
- GTMSessionFetcher/Core (~> 1.1)
- FirebaseCore (4.0.14):
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- FirebaseCrash (2.0.2):
- FirebaseAnalytics (~> 4.0)
- FirebaseInstanceID (~> 2.0)
- GoogleToolboxForMac/Logger (~> 2.1)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- Protobuf (~> 3.1)
- FirebaseDatabase (4.1.4):
- FirebaseAnalytics (~> 4.0)
- FirebaseCore (~> 4.0)
- leveldb-library (~> 1.18)
- FirebaseDynamicLinks (2.3.2):
- FirebaseAnalytics (~> 4.0)
- FirebaseFirestore (0.10.0):
- FirebaseAnalytics (~> 4.0)
- FirebaseCore (~> 4.0)
- gRPC-ProtoRPC (~> 1.0)
- leveldb-library (~> 1.18)
- Protobuf (~> 3.1)
- FirebaseInstanceID (2.0.8):
- FirebaseCore (~> 4.0)
- FirebaseMessaging (2.0.8):
- FirebaseAnalytics (~> 4.0)
- FirebaseCore (~> 4.0)
- FirebaseInstanceID (~> 2.0)
- GoogleToolboxForMac/Logger (~> 2.1)
- Protobuf (~> 3.1)
- FirebasePerformance (1.1.1):
- FirebaseAnalytics (~> 4.0)
- FirebaseInstanceID (~> 2.0)
- FirebaseSwizzlingUtilities (~> 1.0)
- GoogleToolboxForMac/Logger (~> 2.1)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- GTMSessionFetcher/Core (~> 1.1)
- Protobuf (~> 3.1)
- FirebaseRemoteConfig (2.1.1):
- FirebaseABTesting (~> 1.0)
- FirebaseAnalytics (~> 4.0)
- FirebaseCore (~> 4.0)
- FirebaseInstanceID (~> 2.0)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- Protobuf (~> 3.1)
- FirebaseStorage (2.1.2):
- FirebaseAnalytics (~> 4.0)
- FirebaseCore (~> 4.0)
- GTMSessionFetcher/Core (~> 1.1)
- FirebaseSwizzlingUtilities (1.0.0)
- Google-Mobile-Ads-SDK (7.27.0)
- GoogleToolboxForMac/DebugUtils (2.1.3):
- GoogleToolboxForMac/Defines (= 2.1.3)
- GoogleToolboxForMac/Defines (2.1.3)
- GoogleToolboxForMac/Logger (2.1.3):
- GoogleToolboxForMac/Defines (= 2.1.3)
- GoogleToolboxForMac/NSData+zlib (2.1.3):
- GoogleToolboxForMac/Defines (= 2.1.3)
- GoogleToolboxForMac/NSDictionary+URLArguments (2.1.3):
- GoogleToolboxForMac/DebugUtils (= 2.1.3)
- GoogleToolboxForMac/Defines (= 2.1.3)
- GoogleToolboxForMac/NSString+URLArguments (= 2.1.3)
- GoogleToolboxForMac/NSString+URLArguments (2.1.3)
- gRPC (1.8.4):
- gRPC-RxLibrary (= 1.8.4)
- gRPC/Main (= 1.8.4)
- gRPC-Core (1.8.4):
- gRPC-Core/Implementation (= 1.8.4)
- gRPC-Core/Interface (= 1.8.4)
- gRPC-Core/Implementation (1.8.4):
- BoringSSL (~> 9.0)
- gRPC-Core/Interface (= 1.8.4)
- nanopb (~> 0.3)
- gRPC-Core/Interface (1.8.4)
- gRPC-ProtoRPC (1.8.4):
- gRPC (= 1.8.4)
- gRPC-RxLibrary (= 1.8.4)
- Protobuf (~> 3.0)
- gRPC-RxLibrary (1.8.4)
- gRPC/Main (1.8.4):
- gRPC-Core (= 1.8.4)
- gRPC-RxLibrary (= 1.8.4)
- GTMSessionFetcher/Core (1.1.12)
- leveldb-library (1.20)
- nanopb (0.3.8):
- nanopb/decode (= 0.3.8)
- nanopb/encode (= 0.3.8)
- nanopb/decode (0.3.8)
- nanopb/encode (0.3.8)
- Protobuf (3.5.0)
- React (0.52.0):
- React/Core (= 0.52.0)
- React/BatchedBridge (0.52.0):
- React/Core
- React/cxxreact_legacy
- React/Core (0.52.0):
- yoga (= 0.52.0.React)
- React/cxxreact_legacy (0.52.0):
- React/jschelpers_legacy
- React/jsinspector_legacy
- React/fishhook (0.52.0)
- React/jschelpers_legacy (0.52.0)
- React/jsinspector_legacy (0.52.0)
- React/RCTBlob (0.52.0):
- React/Core
- React/RCTNetwork (0.52.0):
- React/Core
- React/RCTText (0.52.0):
- React/Core
- React/RCTWebSocket (0.52.0):
- React/Core
- React/fishhook
- React/RCTBlob
- RNFirebase (3.2.0):
- React
- yoga (0.52.0.React)
DEPENDENCIES:
- Crashlytics (~> 3.9.3)
- Fabric (~> 1.7.2)
- Firebase/AdMob
- Firebase/Auth
- Firebase/Core
- Firebase/Crash
- Firebase/Database
- Firebase/DynamicLinks
- Firebase/Firestore
- Firebase/Messaging
- Firebase/Performance
- Firebase/RemoteConfig
- Firebase/Storage
- React/BatchedBridge (from `../node_modules/react-native`)
- React/Core (from `../node_modules/react-native`)
- React/RCTNetwork (from `../node_modules/react-native`)
- React/RCTText (from `../node_modules/react-native`)
- React/RCTWebSocket (from `../node_modules/react-native`)
- RNFirebase (from `../../ios/RNFirebase.podspec`)
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
EXTERNAL SOURCES:
React:
:path: "../node_modules/react-native"
RNFirebase:
:path: "../../ios/RNFirebase.podspec"
yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
BoringSSL: f3d6b8ce199b9c450a8cfc14895d07a2627fc232
Crashlytics: dbb07d01876c171c5ccbdf7826410380189e452c
Fabric: 9cd6a848efcf1b8b07497e0b6a2e7d336353ba15
Firebase: 2721056b8885eef90233b03f37be64358d35d262
FirebaseABTesting: d07d0ee833b842d5153549e4c7e2e2cb1c23a3f9
FirebaseAnalytics: 617afa8c26b57a0c3f11361b248bc9e17bfd8dfd
FirebaseAuth: bd2738c5c1e92b108ba5f7f7335908097a4e50bb
FirebaseCore: 2e0b98fb2d64ca8140136beff15772bdd14d2dd7
FirebaseCrash: cded0fc566c03651aea606a101bc156085f333ca
FirebaseDatabase: de4446507ccd3257fca37d16f40e1540324571fd
FirebaseDynamicLinks: 38b68641d24e78d0277a9205d988ce22875d5a25
FirebaseFirestore: 713f0c555e7af5ac03d0fec0e2477c48857f4977
FirebaseInstanceID: 81df5805a08001e69138664bdd02c6719a9ac80f
FirebaseMessaging: dfdcd307c2382290a1e297a81d0f18370f5b1bcd
FirebasePerformance: 4e1f8091e400eaf88505234caef5718313653709
FirebaseRemoteConfig: 3310f264fff78b6c2e78b24dcfc4c1b3d6766209
FirebaseStorage: 181bb543d39ee3c53e0558de7ba86b1286a0427f
FirebaseSwizzlingUtilities: f1c49a5a372ac852c853722a5891a0a5e2344a6c
Google-Mobile-Ads-SDK: 83f7f890e638ce8f1debd440ea363338c9f6be3b
GoogleToolboxForMac: 2501e2ad72a52eb3dfe7bd9aee7dad11b858bd20
gRPC: 572520c17b794362388d5c95396329592a3c199b
gRPC-Core: af0d4f0a53735e335fccc815c50c0a03da695287
gRPC-ProtoRPC: 6596fde8d27e0718d7de1de1dc99a951d832a809
gRPC-RxLibrary: f6b1432a667c3354c7b345affed9886c0d4ff549
GTMSessionFetcher: ebaa1f79a5366922c1735f1566901f50beba23b7
leveldb-library: '08cba283675b7ed2d99629a4bc5fd052cd2bb6a5'
nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3
Protobuf: 8a9838fba8dae3389230e1b7f8c104aa32389c03
React: 61a6bdf17a9ff16875c230e6ff278d9de274e16c
RNFirebase: 22b1917fec663706907bc901ed665ac4f8b9bfd6
yoga: 646606bf554d54a16711f35596178522fbc00480
PODFILE CHECKSUM: 67c98bcb203cb992da590bcab6f690f727653ca5
COCOAPODS: 1.2.1

View File

@ -1006,7 +1006,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
6AE1012F46FF8A4D1D818A12 /* [CP] Copy Pods Resources */ = {
@ -1016,7 +1016,7 @@
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-ReactNativeFirebaseDemo/Pods-ReactNativeFirebaseDemo-resources.sh",
$PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle,
"$PODS_CONFIGURATION_BUILD_DIR/gRPC/gRPCCertificates.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (

View File

@ -54,18 +54,22 @@ console.log('RNApps -->', RNfirebase.apps);
// no need for ready checks
instances.native
.auth()
.signInAnonymously()
.then(user => {
console.log('defaultApp user ->', user.toJSON());
.signInAnonymouslyAndRetrieveData()
.then(credential => {
if (credential) {
console.log('anotherApp credential ->', credential.user.toJSON());
}
});
// dynamically initialized apps need a ready check
instances.another.onReady().then(app => {
app
.auth()
.signInAnonymously()
.then(user => {
console.log('anotherApp user ->', user.toJSON());
.signInAnonymouslyAndRetrieveData()
.then(credential => {
if (credential) {
console.log('anotherApp credential ->', credential.user.toJSON());
}
});
});