diff --git a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java index fa6e65e3..7c452efa 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java +++ b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java @@ -12,6 +12,7 @@ import com.facebook.react.bridge.WritableMap; import com.google.firebase.firestore.DocumentChange; import com.google.firebase.firestore.DocumentReference; import com.google.firebase.firestore.DocumentSnapshot; +import com.google.firebase.firestore.FieldPath; import com.google.firebase.firestore.FieldValue; import com.google.firebase.firestore.FirebaseFirestore; import com.google.firebase.firestore.GeoPoint; @@ -269,6 +270,8 @@ public class FirestoreSerialize { } else if ("date".equals(type)) { Double time = typeMap.getDouble("value"); return new Date(time.longValue()); + } else if ("documentid".equals(type)) { + return FieldPath.documentId(); } else if ("fieldvalue".equals(type)) { String value = typeMap.getString("value"); if ("delete".equals(value)) { diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java index bc7925ee..517a0ec3 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java +++ b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreCollectionReference.java @@ -14,6 +14,7 @@ import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.firestore.DocumentListenOptions; import com.google.firebase.firestore.EventListener; +import com.google.firebase.firestore.FieldPath; import com.google.firebase.firestore.FirebaseFirestore; import com.google.firebase.firestore.FirebaseFirestoreException; import com.google.firebase.firestore.ListenerRegistration; @@ -21,6 +22,7 @@ import com.google.firebase.firestore.Query; import com.google.firebase.firestore.QueryListenOptions; import com.google.firebase.firestore.QuerySnapshot; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -128,27 +130,56 @@ public class RNFirebaseFirestoreCollectionReference { private Query applyFilters(FirebaseFirestore firestore, Query query) { for (int i = 0; i < filters.size(); i++) { ReadableMap filter = filters.getMap(i); - String fieldPath = filter.getString("fieldPath"); + ReadableMap fieldPathMap = filter.getMap("fieldPath"); + String fieldPathType = fieldPathMap.getString("type"); + String operator = filter.getString("operator"); ReadableMap jsValue = filter.getMap("value"); Object value = FirestoreSerialize.parseTypeMap(firestore, jsValue); - switch (operator) { - case "EQUAL": - query = query.whereEqualTo(fieldPath, value); - break; - case "GREATER_THAN": - query = query.whereGreaterThan(fieldPath, value); - break; - case "GREATER_THAN_OR_EQUAL": - query = query.whereGreaterThanOrEqualTo(fieldPath, value); - break; - case "LESS_THAN": - query = query.whereLessThan(fieldPath, value); - break; - case "LESS_THAN_OR_EQUAL": - query = query.whereLessThanOrEqualTo(fieldPath, value); - break; + if (fieldPathType.equals("string")) { + String fieldPath = fieldPathMap.getString("string"); + switch (operator) { + case "EQUAL": + query = query.whereEqualTo(fieldPath, value); + break; + case "GREATER_THAN": + query = query.whereGreaterThan(fieldPath, value); + break; + case "GREATER_THAN_OR_EQUAL": + query = query.whereGreaterThanOrEqualTo(fieldPath, value); + break; + case "LESS_THAN": + query = query.whereLessThan(fieldPath, value); + break; + case "LESS_THAN_OR_EQUAL": + query = query.whereLessThanOrEqualTo(fieldPath, value); + break; + } + } else { + ReadableArray fieldPathElements = fieldPathMap.getArray("elements"); + String[] fieldPathArray = new String[fieldPathElements.size()]; + for (int j=0; j order = (Map) o; String direction = (String) order.get("direction"); - String fieldPath = (String) order.get("fieldPath"); + Map fieldPathMap = (Map) order.get("fieldPath"); + String fieldPathType = (String)fieldPathMap.get("type"); - query = query.orderBy(fieldPath, Query.Direction.valueOf(direction)); + if (fieldPathType.equals("string")) { + String fieldPath = (String)fieldPathMap.get("string"); + query = query.orderBy(fieldPath, Query.Direction.valueOf(direction)); + } else { + List fieldPathElements = (List)fieldPathMap.get("elements"); + FieldPath fieldPath = FieldPath.of(fieldPathElements.toArray(new String[fieldPathElements.size()])); + query = query.orderBy(fieldPath, Query.Direction.valueOf(direction)); + } } return query; } diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m b/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m index 91af07cd..d3acff90 100644 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m +++ b/ios/RNFirebase/firestore/RNFirebaseFirestoreCollectionReference.m @@ -93,21 +93,39 @@ queryListenOptions:(NSDictionary *) queryListenOptions { - (FIRQuery *)applyFilters:(FIRFirestore *) firestore query:(FIRQuery *) query { for (NSDictionary *filter in _filters) { - NSString *fieldPath = filter[@"fieldPath"]; + NSDictionary *fieldPathDictionary = filter[@"fieldPath"]; + NSString *fieldPathType = fieldPathDictionary[@"type"]; NSString *operator = filter[@"operator"]; NSDictionary *jsValue = filter[@"value"]; id value = [RNFirebaseFirestoreDocumentReference parseJSTypeMap:firestore jsTypeMap:jsValue]; - if ([operator isEqualToString:@"EQUAL"]) { - query = [query queryWhereField:fieldPath isEqualTo:value]; - } else if ([operator isEqualToString:@"GREATER_THAN"]) { - query = [query queryWhereField:fieldPath isGreaterThan:value]; - } else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) { - query = [query queryWhereField:fieldPath isGreaterThanOrEqualTo:value]; - } else if ([operator isEqualToString:@"LESS_THAN"]) { - query = [query queryWhereField:fieldPath isLessThan:value]; - } else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) { - query = [query queryWhereField:fieldPath isLessThanOrEqualTo:value]; + if ([fieldPathType isEqualToString:@"string"]) { + NSString *fieldPath = fieldPathDictionary[@"string"]; + if ([operator isEqualToString:@"EQUAL"]) { + query = [query queryWhereField:fieldPath isEqualTo:value]; + } else if ([operator isEqualToString:@"GREATER_THAN"]) { + query = [query queryWhereField:fieldPath isGreaterThan:value]; + } else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) { + query = [query queryWhereField:fieldPath isGreaterThanOrEqualTo:value]; + } else if ([operator isEqualToString:@"LESS_THAN"]) { + query = [query queryWhereField:fieldPath isLessThan:value]; + } else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) { + query = [query queryWhereField:fieldPath isLessThanOrEqualTo:value]; + } + } else { + NSArray *fieldPathElements = fieldPathDictionary[@"elements"]; + FIRFieldPath *fieldPath = [[FIRFieldPath alloc] initWithFields:fieldPathElements]; + if ([operator isEqualToString:@"EQUAL"]) { + query = [query queryWhereFieldPath:fieldPath isEqualTo:value]; + } else if ([operator isEqualToString:@"GREATER_THAN"]) { + query = [query queryWhereFieldPath:fieldPath isGreaterThan:value]; + } else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) { + query = [query queryWhereFieldPath:fieldPath isGreaterThanOrEqualTo:value]; + } else if ([operator isEqualToString:@"LESS_THAN"]) { + query = [query queryWhereFieldPath:fieldPath isLessThan:value]; + } else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) { + query = [query queryWhereFieldPath:fieldPath isLessThanOrEqualTo:value]; + } } } return query; @@ -116,9 +134,17 @@ queryListenOptions:(NSDictionary *) queryListenOptions { - (FIRQuery *)applyOrders:(FIRQuery *) query { for (NSDictionary *order in _orders) { NSString *direction = order[@"direction"]; - NSString *fieldPath = order[@"fieldPath"]; + NSDictionary *fieldPathDictionary = order[@"fieldPath"]; + NSString *fieldPathType = fieldPathDictionary[@"type"]; - query = [query queryOrderedByField:fieldPath descending:([direction isEqualToString:@"DESCENDING"])]; + if ([fieldPathType isEqualToString:@"string"]) { + NSString *fieldPath = fieldPathDictionary[@"string"]; + query = [query queryOrderedByField:fieldPath descending:([direction isEqualToString:@"DESCENDING"])]; + } else { + NSArray *fieldPathElements = fieldPathDictionary[@"elements"]; + FIRFieldPath *fieldPath = [[FIRFieldPath alloc] initWithFields:fieldPathElements]; + query = [query queryOrderedByFieldPath:fieldPath descending:([direction isEqualToString:@"DESCENDING"])]; + } } return query; } diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m index ba8ca21b..6fe78759 100644 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m +++ b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m @@ -255,6 +255,8 @@ static NSMutableDictionary *_listeners; return [[FIRGeoPoint alloc] initWithLatitude:[latitude doubleValue] longitude:[longitude doubleValue]]; } else if ([type isEqualToString:@"date"]) { return [NSDate dateWithTimeIntervalSince1970:([(NSNumber *)value doubleValue] / 1000.0)]; + } else if ([type isEqualToString:@"documentid"]) { + return [FIRFieldPath documentID]; } else if ([type isEqualToString:@"fieldvalue"]) { NSString *string = (NSString*)value; if ([string isEqualToString:@"delete"]) { diff --git a/lib/modules/firestore/CollectionReference.js b/lib/modules/firestore/CollectionReference.js index c3cba570..3eb96c01 100644 --- a/lib/modules/firestore/CollectionReference.js +++ b/lib/modules/firestore/CollectionReference.js @@ -8,6 +8,7 @@ import { firestoreAutoId } from '../../utils'; import type Firestore from './'; import type { FirestoreQueryDirection, FirestoreQueryOperator } from '../../types'; +import type FieldPath from './FieldPath'; import type Path from './Path'; import type { Observer, ObserverOnError, ObserverOnNext, QueryListenOptions } from './Query'; import type QuerySnapshot from './QuerySnapshot'; @@ -81,7 +82,7 @@ export default class CollectionReference { return this._query.onSnapshot(optionsOrObserverOrOnNext, observerOrOnNextOrOnError, onError); } - orderBy(fieldPath: string, directionStr?: FirestoreQueryDirection): Query { + orderBy(fieldPath: string | FieldPath, directionStr?: FirestoreQueryDirection): Query { return this._query.orderBy(fieldPath, directionStr); } diff --git a/lib/modules/firestore/DocumentSnapshot.js b/lib/modules/firestore/DocumentSnapshot.js index dc74fe4c..64cce079 100644 --- a/lib/modules/firestore/DocumentSnapshot.js +++ b/lib/modules/firestore/DocumentSnapshot.js @@ -3,12 +3,25 @@ * DocumentSnapshot representation wrapper */ import DocumentReference from './DocumentReference'; +import FieldPath from './FieldPath'; import Path from './Path'; +import { isObject } from '../../utils'; import { parseNativeMap } from './utils/serialize'; import type Firestore from './'; import type { FirestoreNativeDocumentSnapshot, FirestoreSnapshotMetadata } from '../../types'; +const extractFieldPathData = (data: Object | void, segments: string[]): any => { + if (!data || !isObject(data)) { + return undefined; + } + const pathValue = data[segments[0]]; + if (segments.length === 1) { + return pathValue; + } + return extractFieldPathData(pathValue, segments.slice(1)); +}; + /** * @class DocumentSnapshot */ @@ -43,7 +56,10 @@ export default class DocumentSnapshot { return this._data; } - get(fieldPath: string): any { + get(fieldPath: string | FieldPath): any { + if (fieldPath instanceof FieldPath) { + return extractFieldPathData(this._data, fieldPath._segments); + } return this._data ? this._data[fieldPath] : undefined; } } diff --git a/lib/modules/firestore/FieldPath.js b/lib/modules/firestore/FieldPath.js new file mode 100644 index 00000000..202f3309 --- /dev/null +++ b/lib/modules/firestore/FieldPath.js @@ -0,0 +1,22 @@ +/** + * @flow + * FieldPath representation wrapper + */ + +/** + * @class FieldPath + */ +export default class FieldPath { + _segments: string[]; + + constructor(...segments: string[]) { + // TODO: Validation + this._segments = segments; + } + + static documentId(): FieldPath { + return DOCUMENT_ID; + } +} + +export const DOCUMENT_ID = new FieldPath('__name__'); diff --git a/lib/modules/firestore/Query.js b/lib/modules/firestore/Query.js index 5d26f977..cc4190e0 100644 --- a/lib/modules/firestore/Query.js +++ b/lib/modules/firestore/Query.js @@ -3,6 +3,7 @@ * Query representation wrapper */ import DocumentSnapshot from './DocumentSnapshot'; +import FieldPath from './FieldPath'; import QuerySnapshot from './QuerySnapshot'; import { buildNativeArray, buildTypeMap } from './utils/serialize'; import { getAppEventName, SharedEventEmitter } from '../../utils/events'; @@ -30,15 +31,20 @@ const OPERATORS: { [FirestoreQueryOperator]: string } = { '<=': 'LESS_THAN_OR_EQUAL', }; -type FieldFilter = { - fieldPath: string, +type NativeFieldPath = {| + elements?: string[], + string?: string, + type: 'fieldpath' | 'string', +|} +type FieldFilter = {| + fieldPath: NativeFieldPath, operator: string, value: any, -} -type FieldOrder = { +|} +type FieldOrder = {| direction: string, - fieldPath: string, -} + fieldPath: NativeFieldPath, +|} type QueryOptions = { endAt?: any[], endBefore?: any[], @@ -49,10 +55,10 @@ type QueryOptions = { startAt?: any[], } -export type QueryListenOptions = { +export type QueryListenOptions = {| includeDocumentMetadataChanges: boolean, includeQueryMetadataChanges: boolean, -} +|} export type ObserverOnError = (Object) => void; export type ObserverOnNext = (QuerySnapshot) => void; @@ -62,6 +68,19 @@ export type Observer = { next: ObserverOnNext, } +const buildNativeFieldPath = (fieldPath: string | FieldPath): NativeFieldPath => { + if (fieldPath instanceof FieldPath) { + return { + elements: fieldPath._segments, + type: 'fieldpath', + }; + } + return { + string: fieldPath, + type: 'string', + }; +}; + /** * @class Query */ @@ -252,7 +271,7 @@ export default class Query { return this._offCollectionSnapshot.bind(this, listenerId, listener); } - orderBy(fieldPath: string, directionStr?: FirestoreQueryDirection = 'asc'): Query { + orderBy(fieldPath: string | FieldPath, directionStr?: FirestoreQueryDirection = 'asc'): Query { // TODO: Validation // validate.isFieldPath('fieldPath', fieldPath); // validate.isOptionalFieldOrder('directionStr', directionStr); @@ -262,9 +281,9 @@ export default class Query { 'startAt(), startAfter(), endBefore() or endAt().'); } - const newOrder = { + const newOrder: FieldOrder = { direction: DIRECTIONS[directionStr], - fieldPath, + fieldPath: buildNativeFieldPath(fieldPath), }; const combinedOrders = this._fieldOrders.concat(newOrder); return new Query( @@ -306,13 +325,13 @@ export default class Query { ); } - where(fieldPath: string, opStr: FirestoreQueryOperator, value: any): Query { + where(fieldPath: string | FieldPath, opStr: FirestoreQueryOperator, value: any): Query { // TODO: Validation // validate.isFieldPath('fieldPath', fieldPath); // validate.isFieldFilter('fieldFilter', opStr, value); const nativeValue = buildTypeMap(value); - const newFilter = { - fieldPath, + const newFilter: FieldFilter = { + fieldPath: buildNativeFieldPath(fieldPath), operator: OPERATORS[opStr], value: nativeValue, }; @@ -334,11 +353,16 @@ export default class Query { // TODO: Validation let values; if (snapshotOrVarArgs.length === 1 && snapshotOrVarArgs[0] instanceof DocumentSnapshot) { - const docSnapshot = snapshotOrVarArgs[0]; + const docSnapshot: DocumentSnapshot = snapshotOrVarArgs[0]; values = []; for (let i = 0; i < this._fieldOrders.length; i++) { const fieldOrder = this._fieldOrders[i]; - values.push(docSnapshot.get(fieldOrder.fieldPath)); + if (fieldOrder.fieldPath.type === 'string' && fieldOrder.fieldPath.string) { + values.push(docSnapshot.get(fieldOrder.fieldPath.string)); + } else if (fieldOrder.fieldPath.fieldpath) { + const fieldPath = new FieldPath(...fieldOrder.fieldPath.fieldpath); + values.push(docSnapshot.get(fieldPath)); + } } } else { values = snapshotOrVarArgs; diff --git a/lib/modules/firestore/index.js b/lib/modules/firestore/index.js index 029b002e..d58c5714 100644 --- a/lib/modules/firestore/index.js +++ b/lib/modules/firestore/index.js @@ -8,6 +8,7 @@ import { getAppEventName, SharedEventEmitter } from '../../utils/events'; import ModuleBase from '../../utils/ModuleBase'; import CollectionReference from './CollectionReference'; import DocumentReference from './DocumentReference'; +import FieldPath from './FieldPath'; import FieldValue from './FieldValue'; import GeoPoint from './GeoPoint'; import Path from './Path'; @@ -148,6 +149,7 @@ export default class Firestore extends ModuleBase { } export const statics = { + FieldPath, FieldValue, GeoPoint, enableLogging(enabled: boolean) { diff --git a/lib/modules/firestore/utils/serialize.js b/lib/modules/firestore/utils/serialize.js index a3ae0c50..f243e02e 100644 --- a/lib/modules/firestore/utils/serialize.js +++ b/lib/modules/firestore/utils/serialize.js @@ -3,6 +3,7 @@ */ import DocumentReference from '../DocumentReference'; +import { DOCUMENT_ID } from '../FieldPath'; import { DELETE_FIELD_VALUE, SERVER_TIMESTAMP_FIELD_VALUE } from '../FieldValue'; import GeoPoint from '../GeoPoint'; import Path from '../Path'; @@ -60,6 +61,10 @@ export const buildTypeMap = (value: any): FirestoreTypeMap | null => { type: 'fieldvalue', value: 'timestamp', }; + } else if (value === DOCUMENT_ID) { + return { + type: 'documentid', + }; } else if (type === 'boolean' || type === 'number' || type === 'string') { return { type, diff --git a/tests/src/tests/firestore/collectionReferenceTests.js b/tests/src/tests/firestore/collectionReferenceTests.js index 47fe4d88..0ce32389 100644 --- a/tests/src/tests/firestore/collectionReferenceTests.js +++ b/tests/src/tests/firestore/collectionReferenceTests.js @@ -500,6 +500,19 @@ function collectionReferenceTests({ describe, it, context, firebase, before, aft }); }); }); + + it('correctly handles FieldPath', () => { + return firebase.native.firestore() + .collection('collection-tests') + .where(new firebase.native.firestore.FieldPath('baz'), '==', true) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 1); + querySnapshot.forEach((documentSnapshot) => { + should.equal(documentSnapshot.data().baz, true); + }); + }); + }); }); context('limit', () => { @@ -614,6 +627,31 @@ function collectionReferenceTests({ describe, it, context, firebase, before, aft ); }); }); + + it('works with FieldPath', () => { + return collectionTests.orderBy(new firebase.native.firestore.FieldPath('timestamp')).endAt(new Date(2017, 2, 12, 10, 0, 0)) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 3); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [123, 234, 345], + ); + }); + }); + + it('handles snapshots with FieldPath', async () => { + const collectionSnapshot = await collectionTests.orderBy(new firebase.native.firestore.FieldPath('foo')).get(); + return collectionTests.orderBy('foo').endAt(collectionSnapshot.docs[2]) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 3); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [123, 234, 345], + ); + }); + }); }); context('endBefore', () => { @@ -665,6 +703,31 @@ function collectionReferenceTests({ describe, it, context, firebase, before, aft ); }); }); + + it('works with FieldPath', () => { + return collectionTests.orderBy(new firebase.native.firestore.FieldPath('timestamp')).endBefore(new Date(2017, 2, 12, 10, 0, 0)) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 2); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [123, 234], + ); + }); + }); + + it('handles snapshots with FieldPath', async () => { + const collectionSnapshot = await collectionTests.orderBy(new firebase.native.firestore.FieldPath('foo')).get(); + return collectionTests.orderBy('foo').endBefore(collectionSnapshot.docs[2]) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 2); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [123, 234], + ); + }); + }); }); context('startAt', () => { @@ -716,6 +779,31 @@ function collectionReferenceTests({ describe, it, context, firebase, before, aft ); }); }); + + it('works with FieldPath', () => { + return collectionTests.orderBy(new firebase.native.firestore.FieldPath('timestamp')).startAt(new Date(2017, 2, 12, 10, 0, 0)) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 3); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [345, 456, 567], + ); + }); + }); + + it('handles snapshots with FieldPath', async () => { + const collectionSnapshot = await collectionTests.orderBy(new firebase.native.firestore.FieldPath('foo')).get(); + return collectionTests.orderBy('foo').startAt(collectionSnapshot.docs[2]) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 3); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [345, 456, 567], + ); + }); + }); }); context('startAfter', () => { @@ -767,6 +855,31 @@ function collectionReferenceTests({ describe, it, context, firebase, before, aft ); }); }); + + it('works with FieldPath', () => { + return collectionTests.orderBy(new firebase.native.firestore.FieldPath('timestamp')).startAfter(new Date(2017, 2, 12, 10, 0, 0)) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 2); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [456, 567], + ); + }); + }); + + it('handles snapshots with FieldPath', async () => { + const collectionSnapshot = await collectionTests.orderBy(new firebase.native.firestore.FieldPath('foo')).get(); + return collectionTests.orderBy('foo').startAfter(collectionSnapshot.docs[2]) + .get() + .then((querySnapshot) => { + should.equal(querySnapshot.size, 2); + should.deepEqual( + querySnapshot.docs.map(doc => doc.data().daz), + [456, 567], + ); + }); + }); }); context('onSnapshot()', () => { diff --git a/tests/src/tests/firestore/fieldPathTests.js b/tests/src/tests/firestore/fieldPathTests.js new file mode 100644 index 00000000..356aeeb7 --- /dev/null +++ b/tests/src/tests/firestore/fieldPathTests.js @@ -0,0 +1,22 @@ +import should from 'should'; + + +function fieldPathTests({ describe, it, context, firebase }) { + describe('FieldPath', () => { + context('DocumentSnapshot.get()', () => { + it('should get the correct values', () => { + return firebase.native.firestore() + .doc('collection-tests/col1') + .get() + .then((snapshot) => { + should.equal(snapshot.get('foo'), 'bar'); + should.equal(snapshot.get(new firebase.native.firestore.FieldPath('foo')), 'bar'); + should.equal(snapshot.get(new firebase.native.firestore.FieldPath('object', 'daz')), 123); + should.equal(snapshot.get(new firebase.native.firestore.FieldPath('nonexistent', 'object')), undefined); + }); + }); + }); + }); +} + +export default fieldPathTests; diff --git a/tests/src/tests/firestore/index.js b/tests/src/tests/firestore/index.js index fea39013..2f97dd86 100644 --- a/tests/src/tests/firestore/index.js +++ b/tests/src/tests/firestore/index.js @@ -6,6 +6,7 @@ import TestSuite from '../../../lib/TestSuite'; */ import collectionReferenceTests from './collectionReferenceTests'; import documentReferenceTests from './documentReferenceTests'; +import fieldPathTests from './fieldPathTests'; import fieldValueTests from './fieldValueTests'; import firestoreTests from './firestoreTests'; @@ -30,6 +31,7 @@ const suite = new TestSuite('Firestore', 'firebase.firestore()', firebase); const testGroups = [ collectionReferenceTests, documentReferenceTests, + fieldPathTests, fieldValueTests, firestoreTests, ];