mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-04-24 04:24:52 +08:00
[firestore][android][js] Add document onSnapshot support plus tests
This commit is contained in:
@@ -19,6 +19,9 @@ export type WriteResult = {
|
||||
writeTime: string,
|
||||
}
|
||||
|
||||
// track all event registrations
|
||||
let listeners = 0;
|
||||
|
||||
/**
|
||||
* @class DocumentReference
|
||||
*/
|
||||
@@ -89,8 +92,30 @@ export default class DocumentReference {
|
||||
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('DocumentReference', 'getCollections'));
|
||||
}
|
||||
|
||||
onSnapshot(onNext: () => any, onError?: () => any): () => void {
|
||||
// TODO
|
||||
onSnapshot(onNext: Function, onError?: Function): () => void {
|
||||
// TODO: Validation
|
||||
const listenerId = listeners++;
|
||||
|
||||
// Listen to snapshot events
|
||||
this._firestore.on(
|
||||
this._firestore._getAppEventName(`onDocumentSnapshot:${listenerId}`),
|
||||
onNext,
|
||||
);
|
||||
|
||||
// Listen for snapshot error events
|
||||
if (onError) {
|
||||
this._firestore.on(
|
||||
this._firestore._getAppEventName(`onDocumentSnapshotError:${listenerId}`),
|
||||
onError,
|
||||
);
|
||||
}
|
||||
|
||||
// Add the native listener
|
||||
this._firestore._native
|
||||
.documentOnSnapshot(this.path, listenerId);
|
||||
|
||||
// Return an unsubscribe method
|
||||
return this._offDocumentSnapshot.bind(this, listenerId, onNext);
|
||||
}
|
||||
|
||||
set(data: { [string]: any }, writeOptions?: WriteOptions): Promise<WriteResult> {
|
||||
@@ -105,16 +130,11 @@ export default class DocumentReference {
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNALS
|
||||
* Remove auth change listener
|
||||
* @param listener
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate a string that uniquely identifies this DocumentReference
|
||||
*
|
||||
* @return {string}
|
||||
* @private
|
||||
*/
|
||||
_getDocumentKey() {
|
||||
return `$${this._firestore._appName}$/${this.path}`;
|
||||
_offDocumentSnapshot(listenerId: number, listener: Function) {
|
||||
this._firestore.log.info('Removing onDocumentSnapshot listener');
|
||||
this._firestore.removeListener(this._firestore._getAppEventName(`onDocumentSnapshot:${listenerId}`), listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ export default class Query {
|
||||
}
|
||||
|
||||
stream(): Stream<DocumentSnapshot> {
|
||||
|
||||
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('Query', 'stream'));
|
||||
}
|
||||
|
||||
where(fieldPath: string, opStr: Operator, value: any): Query {
|
||||
|
||||
@@ -16,6 +16,14 @@ import INTERNALS from './../../internals';
|
||||
const unquotedIdentifier_ = '(?:[A-Za-z_][A-Za-z_0-9]*)';
|
||||
const UNQUOTED_IDENTIFIER_REGEX = new RegExp(`^${unquotedIdentifier_}$`);
|
||||
|
||||
type DocumentSyncEvent = {
|
||||
appName: string,
|
||||
document?: DocumentSnapshot,
|
||||
error?: Object,
|
||||
listenerId: number,
|
||||
path: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Firestore
|
||||
*/
|
||||
@@ -28,6 +36,20 @@ export default class Firestore extends ModuleBase {
|
||||
constructor(firebaseApp: Object, options: Object = {}) {
|
||||
super(firebaseApp, options, true);
|
||||
this._referencePath = new Path([]);
|
||||
|
||||
this.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onCollectionSnapshot
|
||||
this._getAppEventName('firestore_collection_sync_event'),
|
||||
this._onCollectionSyncEvent.bind(this),
|
||||
);
|
||||
|
||||
this.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onDocumentSnapshot
|
||||
this._getAppEventName('firestore_document_sync_event'),
|
||||
this._onDocumentSyncEvent.bind(this),
|
||||
);
|
||||
}
|
||||
|
||||
batch(): WriteBatch {
|
||||
@@ -107,6 +129,37 @@ export default class Firestore extends ModuleBase {
|
||||
|
||||
return fieldPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNALS
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal collection sync listener
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
_onCollectionSyncEvent(event: DocumentSyncEvent) {
|
||||
if (event.error) {
|
||||
this.emit(this._getAppEventName(`onCollectionSnapshotError:${event.listenerId}`, event.error));
|
||||
} else {
|
||||
this.emit(this._getAppEventName(`onCollectionSnapshot:${event.listenerId}`, event.document));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal document sync listener
|
||||
* @param event
|
||||
* @private
|
||||
*/
|
||||
_onDocumentSyncEvent(event: DocumentSyncEvent) {
|
||||
if (event.error) {
|
||||
this.emit(this._getAppEventName(`onDocumentSnapshotError:${event.listenerId}`), event.error);
|
||||
} else {
|
||||
const snapshot = new DocumentSnapshot(this, event.document);
|
||||
this.emit(this._getAppEventName(`onDocumentSnapshot:${event.listenerId}`), snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {
|
||||
|
||||
@@ -29,6 +29,10 @@ const NATIVE_MODULE_EVENTS = {
|
||||
'database_transaction_event',
|
||||
// 'database_server_offset', // TODO
|
||||
],
|
||||
Firestore: [
|
||||
'firestore_collection_sync_event',
|
||||
'firestore_document_sync_event',
|
||||
],
|
||||
};
|
||||
|
||||
const DEFAULTS = {
|
||||
|
||||
Reference in New Issue
Block a user