[firestore][ios] Type map changes for iOS
This commit is contained in:
parent
b8751262b7
commit
7c95ceca5b
|
@ -274,7 +274,7 @@ public class FirestoreSerialize {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "parseTypeMap", new RuntimeException("Cannot convert object of type " + type));
|
Log.e(TAG, "parseTypeMap: Cannot convert object of type " + type);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ RCT_EXPORT_METHOD(documentBatch:(NSString *) appName
|
||||||
for (NSDictionary *write in writes) {
|
for (NSDictionary *write in writes) {
|
||||||
NSString *type = write[@"type"];
|
NSString *type = write[@"type"];
|
||||||
NSString *path = write[@"path"];
|
NSString *path = write[@"path"];
|
||||||
NSDictionary *data = write[@"data"];
|
NSDictionary *data = [RNFirebaseFirestoreDocumentReference parseJSMap:firestore jsMap:write[@"data"]];
|
||||||
|
|
||||||
FIRDocumentReference *ref = [firestore documentWithPath:path];
|
FIRDocumentReference *ref = [firestore documentWithPath:path];
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
- (void)update:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
- (void)update:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||||
- (BOOL)hasListeners;
|
- (BOOL)hasListeners;
|
||||||
+ (NSDictionary *)snapshotToDictionary:(FIRDocumentSnapshot *)documentSnapshot;
|
+ (NSDictionary *)snapshotToDictionary:(FIRDocumentSnapshot *)documentSnapshot;
|
||||||
|
+(NSDictionary *)parseJSMap:(FIRFirestore *) firestore jsMap:(NSDictionary *) jsMap;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -89,12 +89,13 @@ static NSMutableDictionary *_listeners;
|
||||||
options:(NSDictionary *) options
|
options:(NSDictionary *) options
|
||||||
resolver:(RCTPromiseResolveBlock) resolve
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
rejecter:(RCTPromiseRejectBlock) reject {
|
rejecter:(RCTPromiseRejectBlock) reject {
|
||||||
|
NSDictionary *dictionary = [RNFirebaseFirestoreDocumentReference parseJSMap:[RNFirebaseFirestore getFirestoreForApp:_app] jsMap:data];
|
||||||
if (options && options[@"merge"]) {
|
if (options && options[@"merge"]) {
|
||||||
[_ref setData:data options:[FIRSetOptions merge] completion:^(NSError * _Nullable error) {
|
[_ref setData:dictionary options:[FIRSetOptions merge] completion:^(NSError * _Nullable error) {
|
||||||
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
[_ref setData:data completion:^(NSError * _Nullable error) {
|
[_ref setData:dictionary completion:^(NSError * _Nullable error) {
|
||||||
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -103,7 +104,8 @@ static NSMutableDictionary *_listeners;
|
||||||
- (void)update:(NSDictionary *) data
|
- (void)update:(NSDictionary *) data
|
||||||
resolver:(RCTPromiseResolveBlock) resolve
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
rejecter:(RCTPromiseRejectBlock) reject {
|
rejecter:(RCTPromiseRejectBlock) reject {
|
||||||
[_ref updateData:data completion:^(NSError * _Nullable error) {
|
NSDictionary *dictionary = [RNFirebaseFirestoreDocumentReference parseJSMap:[RNFirebaseFirestore getFirestoreForApp:_app] jsMap:data];
|
||||||
|
[_ref updateData:dictionary completion:^(NSError * _Nullable error) {
|
||||||
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -126,7 +128,7 @@ static NSMutableDictionary *_listeners;
|
||||||
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
|
||||||
[snapshot setValue:documentSnapshot.reference.path forKey:@"path"];
|
[snapshot setValue:documentSnapshot.reference.path forKey:@"path"];
|
||||||
if (documentSnapshot.exists) {
|
if (documentSnapshot.exists) {
|
||||||
[snapshot setValue:documentSnapshot.data forKey:@"data"];
|
[snapshot setValue:[RNFirebaseFirestoreDocumentReference buildNativeMap:documentSnapshot.data] forKey:@"data"];
|
||||||
}
|
}
|
||||||
if (documentSnapshot.metadata) {
|
if (documentSnapshot.metadata) {
|
||||||
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
|
||||||
|
@ -159,6 +161,121 @@ static NSMutableDictionary *_listeners;
|
||||||
[_emitter sendEventWithName:FIRESTORE_DOCUMENT_SYNC_EVENT body:event];
|
[_emitter sendEventWithName:FIRESTORE_DOCUMENT_SYNC_EVENT body:event];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+ (NSDictionary *)buildNativeMap:(NSDictionary *)nativeMap {
|
||||||
|
NSMutableDictionary *map = [[NSMutableDictionary alloc] init];
|
||||||
|
[nativeMap enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
|
||||||
|
NSDictionary *typeMap = [RNFirebaseFirestoreDocumentReference buildTypeMap:obj];
|
||||||
|
map[key] = typeMap;
|
||||||
|
}];
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSArray *)buildNativeArray:(NSArray *)nativeArray {
|
||||||
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||||
|
[nativeArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
NSDictionary *typeMap = [RNFirebaseFirestoreDocumentReference buildTypeMap:obj];
|
||||||
|
[array addObject:typeMap];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSDictionary *)buildTypeMap:(id) value {
|
||||||
|
NSMutableDictionary *typeMap = [[NSMutableDictionary alloc] init];
|
||||||
|
if (!value) {
|
||||||
|
typeMap[@"type"] = @"null";
|
||||||
|
} else if ([value isKindOfClass:[NSString class]]) {
|
||||||
|
typeMap[@"type"] = @"string";
|
||||||
|
typeMap[@"value"] = value;
|
||||||
|
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||||
|
typeMap[@"type"] = @"object";
|
||||||
|
typeMap[@"value"] = [RNFirebaseFirestoreDocumentReference buildNativeMap:value];
|
||||||
|
} else if ([value isKindOfClass:[NSArray class]]) {
|
||||||
|
typeMap[@"type"] = @"array";
|
||||||
|
typeMap[@"value"] = [RNFirebaseFirestoreDocumentReference buildNativeArray:value];
|
||||||
|
} else if ([value isKindOfClass:[FIRDocumentReference class]]) {
|
||||||
|
typeMap[@"type"] = @"reference";
|
||||||
|
FIRDocumentReference *ref = (FIRDocumentReference *)value;
|
||||||
|
typeMap[@"value"] = [ref path];
|
||||||
|
} else if ([value isKindOfClass:[FIRGeoPoint class]]) {
|
||||||
|
typeMap[@"type"] = @"geopoint";
|
||||||
|
FIRGeoPoint *point = (FIRGeoPoint *)value;
|
||||||
|
NSMutableDictionary *geopoint = [[NSMutableDictionary alloc] init];
|
||||||
|
geopoint[@"latitude"] = @([point latitude]);
|
||||||
|
geopoint[@"longitude"] = @([point longitude]);
|
||||||
|
typeMap[@"value"] = geopoint;
|
||||||
|
} else if ([value isKindOfClass:[NSDate class]]) {
|
||||||
|
typeMap[@"type"] = @"date";
|
||||||
|
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||||
|
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
|
||||||
|
typeMap[@"value"] = [dateFormatter stringFromDate:(NSDate *)value];
|
||||||
|
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||||
|
NSNumber *number = (NSNumber *)value;
|
||||||
|
if (number == (void*)kCFBooleanFalse || number == (void*)kCFBooleanTrue) {
|
||||||
|
typeMap[@"type"] = @"boolean";
|
||||||
|
} else {
|
||||||
|
typeMap[@"type"] = @"number";
|
||||||
|
}
|
||||||
|
typeMap[@"value"] = value;
|
||||||
|
} else {
|
||||||
|
// TODO: Log an error
|
||||||
|
typeMap[@"type"] = @"null";
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSDictionary *)parseJSMap:(FIRFirestore *) firestore
|
||||||
|
jsMap:(NSDictionary *) jsMap {
|
||||||
|
NSMutableDictionary* map = [[NSMutableDictionary alloc] init];
|
||||||
|
if (jsMap) {
|
||||||
|
[jsMap enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
|
||||||
|
map[key] = [RNFirebaseFirestoreDocumentReference parseJSTypeMap:firestore jsTypeMap:obj];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(NSArray *)parseJSArray:(FIRFirestore *) firestore
|
||||||
|
jsArray:(NSArray *) jsArray {
|
||||||
|
NSMutableArray* array = [[NSMutableArray alloc] init];
|
||||||
|
if (jsArray) {
|
||||||
|
[jsArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
[array addObject:[RNFirebaseFirestoreDocumentReference parseJSTypeMap:firestore jsTypeMap:obj]];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(id)parseJSTypeMap:(FIRFirestore *) firestore
|
||||||
|
jsTypeMap:(NSDictionary *) jsTypeMap {
|
||||||
|
NSString *type = jsTypeMap[@"type"];
|
||||||
|
id value = jsTypeMap[@"value"];
|
||||||
|
if ([type isEqualToString:@"array"]) {
|
||||||
|
return [RNFirebaseFirestoreDocumentReference parseJSArray:firestore jsArray:value];
|
||||||
|
} else if ([type isEqualToString:@"object"]) {
|
||||||
|
return [RNFirebaseFirestoreDocumentReference parseJSMap:firestore jsMap:value];
|
||||||
|
} else if ([type isEqualToString:@"reference"]) {
|
||||||
|
return [firestore documentWithPath:value];
|
||||||
|
} else if ([type isEqualToString:@"geopoint"]) {
|
||||||
|
NSDictionary* geopoint = (NSDictionary*)value;
|
||||||
|
NSNumber *latitude = geopoint[@"latitude"];
|
||||||
|
NSNumber *longitude = geopoint[@"longitude"];
|
||||||
|
return [[FIRGeoPoint alloc] initWithLatitude:[latitude doubleValue] longitude:[longitude doubleValue]];
|
||||||
|
} else if ([type isEqualToString:@"date"]) {
|
||||||
|
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||||
|
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
|
||||||
|
return [dateFormatter dateFromString:value];
|
||||||
|
} else if ([type isEqualToString:@"boolean"] || [type isEqualToString:@"number"] || [type isEqualToString:@"string"] || [type isEqualToString:@"null"]) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
// TODO: Log error
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -412,6 +412,18 @@ function documentReferenceTests({ describe, it, context, firebase }) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context('types', () => {
|
||||||
|
it('should handle Boolean field', async () => {
|
||||||
|
const docRef = firebase.native.firestore().doc('document-tests/reference');
|
||||||
|
await docRef.set({
|
||||||
|
field: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const doc = await docRef.get();
|
||||||
|
should.equal(doc.data().field, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
context('types', () => {
|
context('types', () => {
|
||||||
it('should handle Date field', async () => {
|
it('should handle Date field', async () => {
|
||||||
const docRef = firebase.native.firestore().doc('document-tests/reference');
|
const docRef = firebase.native.firestore().doc('document-tests/reference');
|
||||||
|
|
Loading…
Reference in New Issue