DocumentSnapshot<T>.fromUpdateMap constructor
DocumentSnapshot<T>.fromUpdateMap (
- DocumentReference<
T> ref, - UpdateMap data
Implementation
factory DocumentSnapshot.fromUpdateMap(
DocumentReference<T> ref,
UpdateMap data,
) {
final serializer = ref.firestore._serializer;
/// Merges 'value' at the field path specified by the path array into
/// 'target'.
ApiMapValue? merge({
required ApiMapValue target,
required Object? value,
required List<String> path,
required int pos,
}) {
final key = path[pos];
final isLast = pos == path.length - 1;
if (!target.containsKey(key)) {
if (isLast) {
if (value is _FieldTransform) {
// If there is already data at this path, we need to retain it.
// Otherwise, we don't include it in the DocumentSnapshot.
return target.isNotEmpty ? target : null;
}
// The merge is done
final leafNode = serializer.encodeValue(value);
if (leafNode != null) {
target[key] = leafNode;
}
return target;
} else {
// We need to expand the target object.
final childNode = <String, firestore1.Value>{};
final nestedValue = merge(
target: childNode,
value: value,
path: path,
pos: pos + 1,
);
if (nestedValue != null) {
target[key] = firestore1.Value(
mapValue: firestore1.MapValue(fields: nestedValue),
);
return target;
} else {
return target.isNotEmpty ? target : null;
}
}
} else {
assert(!isLast, "Can't merge current value into a nested object");
target[key] = firestore1.Value(
mapValue: firestore1.MapValue(
fields: merge(
target: target[key]!.mapValue!.fields!,
value: value,
path: path,
pos: pos + 1,
),
),
);
return target;
}
}
final res = <String, firestore1.Value>{};
for (final entry in data.entries) {
final path = entry.key._toList();
merge(target: res, value: entry.value, path: path, pos: 0);
}
return DocumentSnapshot._(
ref: ref,
fieldsProto: firestore1.MapValue(fields: res),
readTime: null,
createTime: null,
updateTime: null,
);
}