[firestore] Add metadata and bring methods in sync with web SDK reference

This commit is contained in:
Chris Bianca 2017-10-05 10:18:24 +01:00
parent 870cb4ebe1
commit f350c2b3ed
14 changed files with 102 additions and 241 deletions

View File

@ -20,6 +20,7 @@ public class FirestoreSerialize {
private static final String KEY_DOC_CHANGE_OLD_INDEX = "oldIndex"; private static final String KEY_DOC_CHANGE_OLD_INDEX = "oldIndex";
private static final String KEY_DOC_CHANGE_TYPE = "type"; private static final String KEY_DOC_CHANGE_TYPE = "type";
private static final String KEY_DOCUMENTS = "documents"; private static final String KEY_DOCUMENTS = "documents";
private static final String KEY_METADATA = "metadata";
private static final String KEY_PATH = "path"; private static final String KEY_PATH = "path";
/** /**
@ -35,10 +36,13 @@ public class FirestoreSerialize {
if (documentSnapshot.exists()) { if (documentSnapshot.exists()) {
documentMap.putMap(KEY_DATA, objectMapToWritable(documentSnapshot.getData())); documentMap.putMap(KEY_DATA, objectMapToWritable(documentSnapshot.getData()));
} }
// Missing fields from web SDK // metadata
// createTime if (documentSnapshot.getMetadata() != null) {
// readTime WritableMap metadata = Arguments.createMap();
// updateTime metadata.putBoolean("fromCache", documentSnapshot.getMetadata().isFromCache());
metadata.putBoolean("hasPendingWrites", documentSnapshot.getMetadata().hasPendingWrites());
documentMap.putMap(KEY_METADATA, metadata);
}
return documentMap; return documentMap;
} }
@ -57,6 +61,14 @@ public class FirestoreSerialize {
} }
queryMap.putArray(KEY_DOCUMENTS, documents); queryMap.putArray(KEY_DOCUMENTS, documents);
// metadata
if (querySnapshot.getMetadata() != null) {
WritableMap metadata = Arguments.createMap();
metadata.putBoolean("fromCache", querySnapshot.getMetadata().isFromCache());
metadata.putBoolean("hasPendingWrites", querySnapshot.getMetadata().hasPendingWrites());
queryMap.putMap(KEY_METADATA, metadata);
}
return queryMap; return queryMap;
} }

View File

@ -65,7 +65,7 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
@ReactMethod @ReactMethod
public void documentBatch(final String appName, final ReadableArray writes, public void documentBatch(final String appName, final ReadableArray writes,
final ReadableMap commitOptions, final Promise promise) { final Promise promise) {
FirebaseFirestore firestore = getFirestoreForApp(appName); FirebaseFirestore firestore = getFirestoreForApp(appName);
WriteBatch batch = firestore.batch(); WriteBatch batch = firestore.batch();
final List<Object> writesArray = Utils.recursivelyDeconstructReadableArray(writes); final List<Object> writesArray = Utils.recursivelyDeconstructReadableArray(writes);
@ -100,16 +100,10 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
@Override @Override
public void onComplete(@NonNull Task<Void> task) { public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) { if (task.isSuccessful()) {
Log.d(TAG, "set:onComplete:success"); Log.d(TAG, "documentBatch:onComplete:success");
WritableArray result = Arguments.createArray(); promise.resolve(null);
for (Object w : writesArray) {
// Missing fields from web SDK
// writeTime
result.pushMap(Arguments.createMap());
}
promise.resolve(result);
} else { } else {
Log.e(TAG, "set:onComplete:failure", task.getException()); Log.e(TAG, "documentBatch:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException()); RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException());
} }
} }
@ -129,9 +123,9 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
} }
@ReactMethod @ReactMethod
public void documentDelete(String appName, String path, ReadableMap options, final Promise promise) { public void documentDelete(String appName, String path, final Promise promise) {
RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path);
ref.delete(options, promise); ref.delete(promise);
} }
@ReactMethod @ReactMethod
@ -249,63 +243,67 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
break; break;
case CANCELLED: case CANCELLED:
code = ErrorUtils.getCodeWithService(service, "cancelled"); code = ErrorUtils.getCodeWithService(service, "cancelled");
message = ErrorUtils.getMessageWithService("Cancelled.", service, code); message = ErrorUtils.getMessageWithService("The operation was cancelled (typically by the caller).", service, code);
break; break;
case UNKNOWN: case UNKNOWN:
code = ErrorUtils.getCodeWithService(service, "unknown"); code = ErrorUtils.getCodeWithService(service, "unknown");
message = ErrorUtils.getMessageWithService("An unknown error occurred.", service, code); message = ErrorUtils.getMessageWithService("Unknown error or an error from a different error domain.", service, code);
break; break;
case INVALID_ARGUMENT: case INVALID_ARGUMENT:
code = ErrorUtils.getCodeWithService(service, "invalid-argument"); code = ErrorUtils.getCodeWithService(service, "invalid-argument");
message = ErrorUtils.getMessageWithService("Invalid argument.", service, code); message = ErrorUtils.getMessageWithService("Client specified an invalid argument.", service, code);
break;
case DEADLINE_EXCEEDED:
code = ErrorUtils.getCodeWithService(service, "deadline-exceeded");
message = ErrorUtils.getMessageWithService("Deadline expired before operation could complete.", service, code);
break; break;
case NOT_FOUND: case NOT_FOUND:
code = ErrorUtils.getCodeWithService(service, "not-found"); code = ErrorUtils.getCodeWithService(service, "not-found");
message = ErrorUtils.getMessageWithService("Not found.", service, code); message = ErrorUtils.getMessageWithService("Some requested document was not found.", service, code);
break; break;
case ALREADY_EXISTS: case ALREADY_EXISTS:
code = ErrorUtils.getCodeWithService(service, "already-exists"); code = ErrorUtils.getCodeWithService(service, "already-exists");
message = ErrorUtils.getMessageWithService("Already exists.", service, code); message = ErrorUtils.getMessageWithService("Some document that we attempted to create already exists.", service, code);
break; break;
case PERMISSION_DENIED: case PERMISSION_DENIED:
code = ErrorUtils.getCodeWithService(service, "permission-denied"); code = ErrorUtils.getCodeWithService(service, "permission-denied");
message = ErrorUtils.getMessageWithService("Permission denied.", service, code); message = ErrorUtils.getMessageWithService("The caller does not have permission to execute the specified operation.", service, code);
break; break;
case RESOURCE_EXHAUSTED: case RESOURCE_EXHAUSTED:
code = ErrorUtils.getCodeWithService(service, "resource-exhausted"); code = ErrorUtils.getCodeWithService(service, "resource-exhausted");
message = ErrorUtils.getMessageWithService("Resource exhausted.", service, code); message = ErrorUtils.getMessageWithService("Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space.", service, code);
break; break;
case FAILED_PRECONDITION: case FAILED_PRECONDITION:
code = ErrorUtils.getCodeWithService(service, "failed-precondition"); code = ErrorUtils.getCodeWithService(service, "failed-precondition");
message = ErrorUtils.getMessageWithService("Failed precondition.", service, code); message = ErrorUtils.getMessageWithService("Operation was rejected because the system is not in a state required for the operation`s execution.", service, code);
break; break;
case ABORTED: case ABORTED:
code = ErrorUtils.getCodeWithService(service, "aborted"); code = ErrorUtils.getCodeWithService(service, "aborted");
message = ErrorUtils.getMessageWithService("Aborted.", service, code); message = ErrorUtils.getMessageWithService("The operation was aborted, typically due to a concurrency issue like transaction aborts, etc.", service, code);
break; break;
case OUT_OF_RANGE: case OUT_OF_RANGE:
code = ErrorUtils.getCodeWithService(service, "out-of-range"); code = ErrorUtils.getCodeWithService(service, "out-of-range");
message = ErrorUtils.getMessageWithService("Out of range.", service, code); message = ErrorUtils.getMessageWithService("Operation was attempted past the valid range.", service, code);
break; break;
case UNIMPLEMENTED: case UNIMPLEMENTED:
code = ErrorUtils.getCodeWithService(service, "unimplemented"); code = ErrorUtils.getCodeWithService(service, "unimplemented");
message = ErrorUtils.getMessageWithService("Unimplemented.", service, code); message = ErrorUtils.getMessageWithService("Operation is not implemented or not supported/enabled.", service, code);
break; break;
case INTERNAL: case INTERNAL:
code = ErrorUtils.getCodeWithService(service, "internal"); code = ErrorUtils.getCodeWithService(service, "internal");
message = ErrorUtils.getMessageWithService("Internal.", service, code); message = ErrorUtils.getMessageWithService("Internal errors.", service, code);
break; break;
case UNAVAILABLE: case UNAVAILABLE:
code = ErrorUtils.getCodeWithService(service, "unavailable"); code = ErrorUtils.getCodeWithService(service, "unavailable");
message = ErrorUtils.getMessageWithService("Unavailable.", service, code); message = ErrorUtils.getMessageWithService("The service is currently unavailable.", service, code);
break; break;
case DATA_LOSS: case DATA_LOSS:
code = ErrorUtils.getCodeWithService(service, "data-loss"); code = ErrorUtils.getCodeWithService(service, "data-loss");
message = ErrorUtils.getMessageWithService("Data loss.", service, code); message = ErrorUtils.getMessageWithService("Unrecoverable data loss or corruption.", service, code);
break; break;
case UNAUTHENTICATED: case UNAUTHENTICATED:
code = ErrorUtils.getCodeWithService(service, "unauthenticated"); code = ErrorUtils.getCodeWithService(service, "unauthenticated");
message = ErrorUtils.getMessageWithService("Unauthenticated.", service, code); message = ErrorUtils.getMessageWithService("The request does not have valid authentication credentials for the operation.", service, code);
break; break;
default: default:
code = ErrorUtils.getCodeWithService(service, "unknown"); code = ErrorUtils.getCodeWithService(service, "unknown");

View File

@ -47,15 +47,13 @@ public class RNFirebaseFirestoreDocumentReference {
// Not supported on Android out of the box // Not supported on Android out of the box
} }
public void delete(final ReadableMap options, final Promise promise) { public void delete(final Promise promise) {
this.ref.delete().addOnCompleteListener(new OnCompleteListener<Void>() { this.ref.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override @Override
public void onComplete(@NonNull Task<Void> task) { public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) { if (task.isSuccessful()) {
Log.d(TAG, "delete:onComplete:success"); Log.d(TAG, "delete:onComplete:success");
// Missing fields from web SDK promise.resolve(null);
// writeTime
promise.resolve(Arguments.createMap());
} else { } else {
Log.e(TAG, "delete:onComplete:failure", task.getException()); Log.e(TAG, "delete:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException()); RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException());
@ -122,9 +120,7 @@ public class RNFirebaseFirestoreDocumentReference {
public void onComplete(@NonNull Task<Void> task) { public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) { if (task.isSuccessful()) {
Log.d(TAG, "set:onComplete:success"); Log.d(TAG, "set:onComplete:success");
// Missing fields from web SDK promise.resolve(null);
// writeTime
promise.resolve(Arguments.createMap());
} else { } else {
Log.e(TAG, "set:onComplete:failure", task.getException()); Log.e(TAG, "set:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException()); RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException());
@ -140,9 +136,7 @@ public class RNFirebaseFirestoreDocumentReference {
public void onComplete(@NonNull Task<Void> task) { public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) { if (task.isSuccessful()) {
Log.d(TAG, "update:onComplete:success"); Log.d(TAG, "update:onComplete:success");
// Missing fields from web SDK promise.resolve(null);
// writeTime
promise.resolve(Arguments.createMap());
} else { } else {
Log.e(TAG, "update:onComplete:failure", task.getException()); Log.e(TAG, "update:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException()); RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException)task.getException());

View File

@ -49,7 +49,6 @@ RCT_EXPORT_METHOD(collectionOnSnapshot:(NSString *) appName
RCT_EXPORT_METHOD(documentBatch:(NSString *) appName RCT_EXPORT_METHOD(documentBatch:(NSString *) appName
writes:(NSArray *) writes writes:(NSArray *) writes
commitOptions:(NSDictionary *) commitOptions
resolver:(RCTPromiseResolveBlock) resolve resolver:(RCTPromiseResolveBlock) resolve
rejecter:(RCTPromiseRejectBlock) reject) { rejecter:(RCTPromiseRejectBlock) reject) {
FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appName]; FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appName];
@ -80,13 +79,7 @@ RCT_EXPORT_METHOD(documentBatch:(NSString *) appName
if (error) { if (error) {
[RNFirebaseFirestore promiseRejectException:reject error:error]; [RNFirebaseFirestore promiseRejectException:reject error:error];
} else { } else {
NSMutableArray *result = [[NSMutableArray alloc] init]; resolve(nil);
for (NSDictionary *write in writes) {
// Missing fields from web SDK
// writeTime
[result addObject:@{}];
}
resolve(result);
} }
}]; }];
} }
@ -108,10 +101,9 @@ RCT_EXPORT_METHOD(documentCreate:(NSString *) appName
RCT_EXPORT_METHOD(documentDelete:(NSString *) appName RCT_EXPORT_METHOD(documentDelete:(NSString *) appName
path:(NSString *) path path:(NSString *) path
options:(NSDictionary *) options
resolver:(RCTPromiseResolveBlock) resolve resolver:(RCTPromiseResolveBlock) resolve
rejecter:(RCTPromiseRejectBlock) reject) { rejecter:(RCTPromiseRejectBlock) reject) {
[[self getDocumentForAppPath:appName path:path] delete:options resolver:resolve rejecter:reject]; [[self getDocumentForAppPath:appName path:path] delete:resolve rejecter:reject];
} }
RCT_EXPORT_METHOD(documentGet:(NSString *) appName RCT_EXPORT_METHOD(documentGet:(NSString *) appName

View File

@ -157,6 +157,12 @@ static NSMutableDictionary *_listeners;
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init]; NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
[snapshot setValue:[self documentChangesToArray:querySnapshot.documentChanges] forKey:@"changes"]; [snapshot setValue:[self documentChangesToArray:querySnapshot.documentChanges] forKey:@"changes"];
[snapshot setValue:[self documentSnapshotsToArray:querySnapshot.documents] forKey:@"documents"]; [snapshot setValue:[self documentSnapshotsToArray:querySnapshot.documents] forKey:@"documents"];
if (querySnapshot.metadata) {
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
[metadata setValue:@(querySnapshot.metadata.fromCache) forKey:@"fromCache"];
[metadata setValue:@(querySnapshot.metadata.hasPendingWrites) forKey:@"hasPendingWrites"];
[snapshot setValue:metadata forKey:@"metadata"];
}
return snapshot; return snapshot;
} }

View File

@ -19,7 +19,7 @@
- (id)initWithPath:(RCTEventEmitter *)emitter app:(NSString *)app path:(NSString *)path; - (id)initWithPath:(RCTEventEmitter *)emitter app:(NSString *)app path:(NSString *)path;
- (void)collections:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; - (void)collections:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
- (void)create:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; - (void)create:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
- (void)delete:(NSDictionary *)options resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; - (void)delete:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
- (void)get:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; - (void)get:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
+ (void)offSnapshot:(NSString *)listenerId; + (void)offSnapshot:(NSString *)listenerId;
- (void)onSnapshot:(NSString *)listenerId; - (void)onSnapshot:(NSString *)listenerId;

View File

@ -34,8 +34,7 @@ static NSMutableDictionary *_listeners;
// Not supported on iOS out of the box // Not supported on iOS out of the box
} }
- (void)delete:(NSDictionary *)options - (void)delete:(RCTPromiseResolveBlock) resolve
resolver:(RCTPromiseResolveBlock) resolve
rejecter:(RCTPromiseRejectBlock) reject { rejecter:(RCTPromiseRejectBlock) reject {
[_ref deleteDocumentWithCompletion:^(NSError * _Nullable error) { [_ref deleteDocumentWithCompletion:^(NSError * _Nullable error) {
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject]; [RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
@ -115,9 +114,7 @@ static NSMutableDictionary *_listeners;
if (error) { if (error) {
[RNFirebaseFirestore promiseRejectException:reject error:error]; [RNFirebaseFirestore promiseRejectException:reject error:error];
} else { } else {
// Missing fields from web SDK resolve(nil);
// writeTime
resolve(@{});
} }
} }
@ -127,11 +124,12 @@ static NSMutableDictionary *_listeners;
if (documentSnapshot.exists) { if (documentSnapshot.exists) {
[snapshot setValue:documentSnapshot.data forKey:@"data"]; [snapshot setValue:documentSnapshot.data forKey:@"data"];
} }
// Missing fields from web SDK if (documentSnapshot.metadata) {
// createTime NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
// readTime [metadata setValue:@(documentSnapshot.metadata.fromCache) forKey:@"fromCache"];
// updateTime [metadata setValue:@(documentSnapshot.metadata.hasPendingWrites) forKey:@"hasPendingWrites"];
[snapshot setValue:metadata forKey:@"metadata"];
}
return snapshot; return snapshot;
} }

View File

@ -37,7 +37,7 @@ export default class CollectionReference {
return parentPath ? new DocumentReference(this._firestore, parentPath) : null; return parentPath ? new DocumentReference(this._firestore, parentPath) : null;
} }
add(data: { [string]: any }): Promise<DocumentReference> { add(data: Object): Promise<DocumentReference> {
const documentRef = this.doc(); const documentRef = this.doc();
return documentRef.set(data) return documentRef.set(data)
.then(() => Promise.resolve(documentRef)); .then(() => Promise.resolve(documentRef));

View File

@ -5,21 +5,12 @@
import CollectionReference from './CollectionReference'; import CollectionReference from './CollectionReference';
import DocumentSnapshot from './DocumentSnapshot'; import DocumentSnapshot from './DocumentSnapshot';
import Path from './Path'; import Path from './Path';
import INTERNALS from './../../internals';
import { firestoreAutoId } from '../../utils'; import { firestoreAutoId } from '../../utils';
export type DeleteOptions = {
lastUpdateTime?: string,
}
export type WriteOptions = { export type WriteOptions = {
merge?: boolean, merge?: boolean,
} }
export type WriteResult = {
writeTime: string,
}
/** /**
* @class DocumentReference * @class DocumentReference
*/ */
@ -40,9 +31,9 @@ export default class DocumentReference {
return this._documentPath.id; return this._documentPath.id;
} }
get parent(): CollectionReference | null { get parent(): CollectionReference {
const parentPath = this._documentPath.parent(); const parentPath = this._documentPath.parent();
return parentPath ? new CollectionReference(this._firestore, parentPath) : null; return new CollectionReference(this._firestore, parentPath);
} }
get path(): string { get path(): string {
@ -58,15 +49,9 @@ export default class DocumentReference {
return new CollectionReference(this._firestore, path); return new CollectionReference(this._firestore, path);
} }
create(data: { [string]: any }): Promise<WriteResult> { delete(): Promise<void> {
/* return this._firestore._native
.documentCreate(this.path, data); */
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('DocumentReference', 'create'));
}
delete(deleteOptions?: DeleteOptions): Promise<WriteResult> {
return this._firestore._native return this._firestore._native
.documentDelete(this.path, deleteOptions); .documentDelete(this.path);
} }
get(): Promise<DocumentSnapshot> { get(): Promise<DocumentSnapshot> {
@ -75,21 +60,6 @@ export default class DocumentReference {
.then(result => new DocumentSnapshot(this._firestore, result)); .then(result => new DocumentSnapshot(this._firestore, result));
} }
getCollections(): Promise<CollectionReference[]> {
/* return this._firestore._native
.documentCollections(this.path)
.then((collectionIds) => {
const collections = [];
for (const collectionId of collectionIds) {
collections.push(this.collection(collectionId));
}
return collections;
}); */
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('DocumentReference', 'getCollections'));
}
onSnapshot(onNext: Function, onError?: Function): () => void { onSnapshot(onNext: Function, onError?: Function): () => void {
// TODO: Validation // TODO: Validation
const listenerId = firestoreAutoId(); const listenerId = firestoreAutoId();
@ -121,13 +91,12 @@ export default class DocumentReference {
return this._offDocumentSnapshot.bind(this, listenerId, listener); return this._offDocumentSnapshot.bind(this, listenerId, listener);
} }
set(data: { [string]: any }, writeOptions?: WriteOptions): Promise<WriteResult> { set(data: Object, writeOptions?: WriteOptions): Promise<void> {
return this._firestore._native return this._firestore._native
.documentSet(this.path, data, writeOptions); .documentSet(this.path, data, writeOptions);
} }
// TODO: Update to new update method signature update(data: Object): Promise<void> {
update(data: { [string]: any }): Promise<WriteResult> {
return this._firestore._native return this._firestore._native
.documentUpdate(this.path, data); .documentUpdate(this.path, data);
} }

View File

@ -4,37 +4,30 @@
*/ */
import DocumentReference from './DocumentReference'; import DocumentReference from './DocumentReference';
import Path from './Path'; import Path from './Path';
import INTERNALS from './../../internals';
export type SnapshotMetadata = {
fromCache: boolean,
hasPendingWrites: boolean,
}
export type DocumentSnapshotNativeData = { export type DocumentSnapshotNativeData = {
createTime: string,
data: Object, data: Object,
metadata: SnapshotMetadata,
path: string, path: string,
readTime: string,
updateTime: string,
} }
/** /**
* @class DocumentSnapshot * @class DocumentSnapshot
*/ */
export default class DocumentSnapshot { export default class DocumentSnapshot {
_createTime: string;
_data: Object; _data: Object;
_readTime: string; _metadata: SnapshotMetadata;
_ref: DocumentReference; _ref: DocumentReference;
_updateTime: string;
constructor(firestore: Object, nativeData: DocumentSnapshotNativeData) { constructor(firestore: Object, nativeData: DocumentSnapshotNativeData) {
this._createTime = nativeData.createTime;
this._data = nativeData.data; this._data = nativeData.data;
this._metadata = nativeData.metadata;
this._ref = new DocumentReference(firestore, Path.fromName(nativeData.path)); this._ref = new DocumentReference(firestore, Path.fromName(nativeData.path));
this._readTime = nativeData.readTime;
this._updateTime = nativeData.updateTime;
}
get createTime(): string {
// return this._createTime;
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('DocumentSnapshot', 'createTime'));
} }
get exists(): boolean { get exists(): boolean {
@ -45,20 +38,14 @@ export default class DocumentSnapshot {
return this._ref.id; return this._ref.id;
} }
get readTime(): string { get metadata(): SnapshotMetadata {
// return this._readTime; return _metadata;
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('DocumentSnapshot', 'readTime'));
} }
get ref(): DocumentReference { get ref(): DocumentReference {
return this._ref; return this._ref;
} }
get updateTime(): string {
// return this._updateTime;
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_PROPERTY('DocumentSnapshot', 'updateTime'));
}
data(): Object { data(): Object {
return this._data; return this._data;
} }

View File

@ -104,31 +104,18 @@ export default class Query {
.then(nativeData => new QuerySnapshot(this._firestore, this, nativeData)); .then(nativeData => new QuerySnapshot(this._firestore, this, nativeData));
} }
limit(n: number): Query { limit(limit: number): Query {
// TODO: Validation // TODO: Validation
// validate.isInteger('n', n); // validate.isInteger('n', n);
const options = { const options = {
...this._queryOptions, ...this._queryOptions,
limit: n, limit,
}; };
return new Query(this.firestore, this._referencePath, this._fieldFilters, return new Query(this.firestore, this._referencePath, this._fieldFilters,
this._fieldOrders, options); this._fieldOrders, options);
} }
offset(n: number): Query {
// TODO: Validation
// validate.isInteger('n', n);
/* const options = {
...this._queryOptions,
offset: n,
};
return new Query(this.firestore, this._referencePath, this._fieldFilters,
this._fieldOrders, options); */
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('Query', 'offset'));
}
onSnapshot(onNext: () => any, onError?: () => any): () => void { onSnapshot(onNext: () => any, onError?: () => any): () => void {
// TODO: Validation // TODO: Validation
const listenerId = firestoreAutoId(); const listenerId = firestoreAutoId();
@ -185,31 +172,6 @@ export default class Query {
combinedOrders, this._queryOptions); combinedOrders, this._queryOptions);
} }
select(varArgs: string[]): Query {
/*
varArgs = Array.isArray(arguments[0]) ? arguments[0] : [].slice.call(arguments);
const fieldReferences = [];
if (varArgs.length === 0) {
fieldReferences.push(DOCUMENT_NAME_FIELD);
} else {
for (let i = 0; i < varArgs.length; ++i) {
// TODO: Validation
// validate.isFieldPath(i, args[i]);
fieldReferences.push(varArgs[i]);
}
}
const options = {
...this._queryOptions,
selectFields: fieldReferences,
};
return new Query(this.firestore, this._referencePath, this._fieldFilters,
this._fieldOrders, options);*/
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('Query', 'select'));
}
startAfter(fieldValues: any): Query { startAfter(fieldValues: any): Query {
fieldValues = [].slice.call(arguments); fieldValues = [].slice.call(arguments);
// TODO: Validation // TODO: Validation
@ -234,10 +196,6 @@ export default class Query {
this._fieldOrders, options); this._fieldOrders, options);
} }
stream(): Stream<DocumentSnapshot> {
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_CLASS_METHOD('Query', 'stream'));
}
where(fieldPath: string, opStr: Operator, value: any): Query { where(fieldPath: string, opStr: Operator, value: any): Query {
// TODO: Validation // TODO: Validation
// validate.isFieldPath('fieldPath', fieldPath); // validate.isFieldPath('fieldPath', fieldPath);

View File

@ -7,12 +7,12 @@ import DocumentSnapshot from './DocumentSnapshot';
import Query from './Query'; import Query from './Query';
import type { DocumentChangeNativeData } from './DocumentChange'; import type { DocumentChangeNativeData } from './DocumentChange';
import type { DocumentSnapshotNativeData } from './DocumentSnapshot'; import type { DocumentSnapshotNativeData, SnapshotMetadata } from './DocumentSnapshot';
type QuerySnapshotNativeData = { type QuerySnapshotNativeData = {
changes: DocumentChangeNativeData[], changes: DocumentChangeNativeData[],
documents: DocumentSnapshotNativeData[], documents: DocumentSnapshotNativeData[],
readTime: string, metadata: SnapshotMetadata,
} }
/** /**
@ -21,14 +21,14 @@ type QuerySnapshotNativeData = {
export default class QuerySnapshot { export default class QuerySnapshot {
_changes: DocumentChange[]; _changes: DocumentChange[];
_docs: DocumentSnapshot[]; _docs: DocumentSnapshot[];
_metadata: SnapshotMetadata;
_query: Query; _query: Query;
_readTime: string;
constructor(firestore: Object, query: Query, nativeData: QuerySnapshotNativeData) { constructor(firestore: Object, query: Query, nativeData: QuerySnapshotNativeData) {
this._changes = nativeData.changes.map(change => new DocumentChange(change)); this._changes = nativeData.changes.map(change => new DocumentChange(change));
this._docs = nativeData.documents.map(doc => new DocumentSnapshot(firestore, doc)); this._docs = nativeData.documents.map(doc => new DocumentSnapshot(firestore, doc));
this._metadata = nativeData.metadata;
this._query = query; this._query = query;
this._readTime = nativeData.readTime;
} }
get docChanges(): DocumentChange[] { get docChanges(): DocumentChange[] {
@ -47,8 +47,8 @@ export default class QuerySnapshot {
return this._query; return this._query;
} }
get readTime(): string { get metadata(): SnapshotMetadata {
return this._readTime; return this._metadata;
} }
get size(): number { get size(): number {

View File

@ -4,11 +4,7 @@
*/ */
import DocumentReference from './DocumentReference'; import DocumentReference from './DocumentReference';
import type { DeleteOptions, WriteOptions, WriteResult } from './DocumentReference'; import type { WriteOptions } from './DocumentReference';
type CommitOptions = {
transactionId: string,
}
type DocumentWrite = { type DocumentWrite = {
data?: Object, data?: Object,
@ -29,28 +25,16 @@ export default class WriteBatch {
this._writes = []; this._writes = [];
} }
get firestore(): Object { commit(): Promise<void> {
return this._firestore; return this._firestore._native
.documentBatch(this._writes);
} }
get isEmpty(): boolean { delete(docRef: DocumentReference): WriteBatch {
return this._writes.length === 0;
}
create(docRef: DocumentReference, data: Object): WriteBatch {
// TODO: Validation
// validate.isDocumentReference('docRef', docRef);
// validate.isDocument('data', data);
return this.set(docRef, data, { exists: false });
}
delete(docRef: DocumentReference, deleteOptions?: DeleteOptions): WriteBatch {
// TODO: Validation // TODO: Validation
// validate.isDocumentReference('docRef', docRef); // validate.isDocumentReference('docRef', docRef);
// validate.isOptionalPrecondition('deleteOptions', deleteOptions); // validate.isOptionalPrecondition('deleteOptions', deleteOptions);
this._writes.push({ this._writes.push({
options: deleteOptions,
path: docRef.path, path: docRef.path,
type: 'DELETE', type: 'DELETE',
}); });
@ -75,7 +59,7 @@ export default class WriteBatch {
} }
// TODO: Update to new method signature // TODO: Update to new method signature
update(docRef: DocumentReference, data: { [string]: any }): WriteBatch { update(docRef: DocumentReference, data: Object): WriteBatch {
// TODO: Validation // TODO: Validation
// validate.isDocumentReference('docRef', docRef); // validate.isDocumentReference('docRef', docRef);
// validate.isDocument('data', data, true); // validate.isDocument('data', data, true);
@ -88,9 +72,4 @@ export default class WriteBatch {
return this; return this;
} }
commit(commitOptions?: CommitOptions): Promise<WriteResult[]> {
return this._firestore._native
.documentBatch(this._writes, commitOptions);
}
} }

View File

@ -13,9 +13,6 @@ import Path from './Path';
import WriteBatch from './WriteBatch'; import WriteBatch from './WriteBatch';
import INTERNALS from './../../internals'; import INTERNALS from './../../internals';
const unquotedIdentifier_ = '(?:[A-Za-z_][A-Za-z_0-9]*)';
const UNQUOTED_IDENTIFIER_REGEX = new RegExp(`^${unquotedIdentifier_}$`);
type CollectionSyncEvent = { type CollectionSyncEvent = {
appName: string, appName: string,
querySnapshot?: QuerySnapshot, querySnapshot?: QuerySnapshot,
@ -92,50 +89,20 @@ export default class Firestore extends ModuleBase {
return new DocumentReference(this, path); return new DocumentReference(this, path);
} }
getAll(varArgs: DocumentReference[]): Promise<DocumentSnapshot[]> { enablePersistence(): Promise<void> {
/*varArgs = Array.isArray(arguments[0]) ? arguments[0] : [].slice.call(arguments); throw new Error('Persistence is enabled by default on the Firestore SDKs');
const documents = [];
varArgs.forEach((document) => {
// TODO: Validation
// validate.isDocumentReference(i, varArgs[i]);
documents.push(document.path);
});
return this._native
.documentGetAll(documents)
.then(results => results.map(result => new DocumentSnapshot(this, result)));*/
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD('Query', 'offset'));
} }
getCollections(): Promise<CollectionReference[]> { runTransaction(updateFunction): Promise<any> {
const rootDocument = new DocumentReference(this, this._referencePath); throw new Error('firebase.firestore().runTransaction() coming soon');
return rootDocument.getCollections();
} }
runTransaction(updateFunction, transactionOptions?: Object): Promise { setLogLevel(logLevel: 'debug' | 'error' | 'silent'): void {
throw new Error(INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(Firestore, 'setLogLevel'));
} }
static geoPoint(latitude, longitude): GeoPoint { settings(settings: Object): void {
return new GeoPoint(latitude, longitude); throw new Error('firebase.firestore().settings() coming soon');
}
static fieldPath(varArgs: string[]): string {
varArgs = Array.isArray(arguments[0]) ? arguments[0] : [].slice.call(arguments);
let fieldPath = '';
for (let i = 0; i < varArgs.length; ++i) {
let component = varArgs[i];
// TODO: Validation
// validate.isString(i, component);
if (!UNQUOTED_IDENTIFIER_REGEX.test(component)) {
component = `\`${component.replace(/[`\\]/g, '\\$&')} \``;
}
fieldPath += i !== 0 ? `.${component}` : component;
}
return fieldPath;
} }
/** /**
@ -174,4 +141,5 @@ export const statics = {
delete: () => NativeModules.RNFirebaseFirestore && NativeModules.RNFirebaseFirestore.deleteFieldValue || {}, delete: () => NativeModules.RNFirebaseFirestore && NativeModules.RNFirebaseFirestore.deleteFieldValue || {},
serverTimestamp: () => NativeModules.RNFirebaseFirestore && NativeModules.RNFirebaseFirestore.serverTimestampFieldValue || {} serverTimestamp: () => NativeModules.RNFirebaseFirestore && NativeModules.RNFirebaseFirestore.serverTimestampFieldValue || {}
}, },
GeoPoint,
}; };