aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source/API/FSTUserDataConverter.mm
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/Source/API/FSTUserDataConverter.mm')
-rw-r--r--Firestore/Source/API/FSTUserDataConverter.mm42
1 files changed, 39 insertions, 3 deletions
diff --git a/Firestore/Source/API/FSTUserDataConverter.mm b/Firestore/Source/API/FSTUserDataConverter.mm
index 2794398..6d01c75 100644
--- a/Firestore/Source/API/FSTUserDataConverter.mm
+++ b/Firestore/Source/API/FSTUserDataConverter.mm
@@ -412,7 +412,7 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) {
return self;
}
-- (FSTParsedSetData *)parsedMergeData:(id)input {
+- (FSTParsedSetData *)parsedMergeData:(id)input fieldMask:(nullable NSArray<id> *)fieldMask {
// NOTE: The public API is typed as NSDictionary but we type 'input' as 'id' since we can't trust
// Obj-C to verify the type for us.
if (![input isKindOfClass:[NSDictionary class]]) {
@@ -424,9 +424,45 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) {
path:absl::make_unique<FieldPath>(FieldPath::EmptyPath())];
FSTObjectValue *updateData = (FSTObjectValue *)[self parseData:input context:context];
+ FieldMask convertedFieldMask;
+ std::vector<FieldTransform> convertedFieldTransform;
+
+ if (fieldMask) {
+ __block std::vector<FieldPath> fieldMaskPaths{};
+ [fieldMask enumerateObjectsUsingBlock:^(id fieldPath, NSUInteger idx, BOOL *stop) {
+ FieldPath path{};
+
+ if ([fieldPath isKindOfClass:[NSString class]]) {
+ path = [FIRFieldPath pathWithDotSeparatedString:fieldPath].internalValue;
+ } else if ([fieldPath isKindOfClass:[FIRFieldPath class]]) {
+ path = ((FIRFieldPath *)fieldPath).internalValue;
+ } else {
+ FSTThrowInvalidArgument(
+ @"All elements in mergeFields: must be NSStrings or FIRFieldPaths.");
+ }
+
+ if ([updateData valueForPath:path] == nil) {
+ FSTThrowInvalidArgument(
+ @"Field '%s' is specified in your field mask but missing from your input data.",
+ path.CanonicalString().c_str());
+ }
+
+ fieldMaskPaths.push_back(path);
+ }];
+ convertedFieldMask = FieldMask(fieldMaskPaths);
+ std::copy_if(context.fieldTransforms->begin(), context.fieldTransforms->end(),
+ std::back_inserter(convertedFieldTransform),
+ [&](const FieldTransform &fieldTransform) {
+ return convertedFieldMask.covers(fieldTransform.path());
+ });
+ } else {
+ convertedFieldMask = FieldMask{*context.fieldMask};
+ convertedFieldTransform = *context.fieldTransforms;
+ }
+
return [[FSTParsedSetData alloc] initWithData:updateData
- fieldMask:FieldMask{*context.fieldMask}
- fieldTransforms:*context.fieldTransforms];
+ fieldMask:convertedFieldMask
+ fieldTransforms:convertedFieldTransform];
}
- (FSTParsedSetData *)parsedSetData:(id)input {