Merge branch 'firestore-transactions' of https://github.com/invertase/react-native-firebase into firestore-transactions
This commit is contained in:
commit
d00fa4faa3
|
@ -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,3 +1,4 @@
|
|||
coverage
|
||||
node_modules
|
||||
npm-debug.log
|
||||
*.DS_Store
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
node_modules
|
||||
coverage.android.json
|
||||
coverage.ios.json
|
||||
coverage
|
||||
npm-debug.log
|
||||
*.DS_Store
|
||||
.github
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
|
@ -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 = (
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue