FIRDocumentReference.mm 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * Copyright 2017 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "FIRDocumentReference.h"
  17. #include <memory>
  18. #include <utility>
  19. #import "FIRFirestoreErrors.h"
  20. #import "FIRFirestoreSource.h"
  21. #import "Firestore/Source/API/FIRCollectionReference+Internal.h"
  22. #import "Firestore/Source/API/FIRDocumentReference+Internal.h"
  23. #import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h"
  24. #import "Firestore/Source/API/FIRFirestore+Internal.h"
  25. #import "Firestore/Source/API/FIRListenerRegistration+Internal.h"
  26. #import "Firestore/Source/API/FSTUserDataConverter.h"
  27. #import "Firestore/Source/Core/FSTEventManager.h"
  28. #import "Firestore/Source/Core/FSTQuery.h"
  29. #import "Firestore/Source/Model/FSTDocumentSet.h"
  30. #import "Firestore/Source/Model/FSTFieldValue.h"
  31. #import "Firestore/Source/Util/FSTUsageValidation.h"
  32. #include "Firestore/core/src/firebase/firestore/api/document_reference.h"
  33. #include "Firestore/core/src/firebase/firestore/model/document_key.h"
  34. #include "Firestore/core/src/firebase/firestore/model/precondition.h"
  35. #include "Firestore/core/src/firebase/firestore/model/resource_path.h"
  36. #include "Firestore/core/src/firebase/firestore/util/string_apple.h"
  37. namespace util = firebase::firestore::util;
  38. using firebase::firestore::api::DocumentReference;
  39. using firebase::firestore::core::ParsedSetData;
  40. using firebase::firestore::core::ParsedUpdateData;
  41. using firebase::firestore::model::DocumentKey;
  42. using firebase::firestore::model::Precondition;
  43. using firebase::firestore::model::ResourcePath;
  44. NS_ASSUME_NONNULL_BEGIN
  45. #pragma mark - FIRDocumentReference
  46. @interface FIRDocumentReference ()
  47. - (instancetype)initWithReference:(DocumentReference &&)reference NS_DESIGNATED_INITIALIZER;
  48. @end
  49. @implementation FIRDocumentReference {
  50. DocumentReference _documentReference;
  51. }
  52. - (instancetype)initWithReference:(DocumentReference &&)reference {
  53. if (self = [super init]) {
  54. _documentReference = std::move(reference);
  55. }
  56. return self;
  57. }
  58. #pragma mark - NSObject Methods
  59. - (BOOL)isEqual:(nullable id)other {
  60. if (other == self) return YES;
  61. if (![[other class] isEqual:[self class]]) return NO;
  62. return _documentReference == static_cast<FIRDocumentReference *>(other)->_documentReference;
  63. }
  64. - (NSUInteger)hash {
  65. return _documentReference.Hash();
  66. }
  67. #pragma mark - Public Methods
  68. @dynamic firestore;
  69. - (FIRFirestore *)firestore {
  70. return _documentReference.firestore();
  71. }
  72. - (NSString *)documentID {
  73. return util::WrapNSString(_documentReference.document_id());
  74. }
  75. - (FIRCollectionReference *)parent {
  76. return _documentReference.Parent();
  77. }
  78. - (NSString *)path {
  79. return util::WrapNSString(_documentReference.Path());
  80. }
  81. - (FIRCollectionReference *)collectionWithPath:(NSString *)collectionPath {
  82. if (!collectionPath) {
  83. FSTThrowInvalidArgument(@"Collection path cannot be nil.");
  84. }
  85. return _documentReference.GetCollectionReference(util::MakeString(collectionPath));
  86. }
  87. - (void)setData:(NSDictionary<NSString *, id> *)documentData {
  88. [self setData:documentData merge:NO completion:nil];
  89. }
  90. - (void)setData:(NSDictionary<NSString *, id> *)documentData merge:(BOOL)merge {
  91. [self setData:documentData merge:merge completion:nil];
  92. }
  93. - (void)setData:(NSDictionary<NSString *, id> *)documentData
  94. mergeFields:(NSArray<id> *)mergeFields {
  95. [self setData:documentData mergeFields:mergeFields completion:nil];
  96. }
  97. - (void)setData:(NSDictionary<NSString *, id> *)documentData
  98. completion:(nullable void (^)(NSError *_Nullable error))completion {
  99. [self setData:documentData merge:NO completion:completion];
  100. }
  101. - (void)setData:(NSDictionary<NSString *, id> *)documentData
  102. merge:(BOOL)merge
  103. completion:(nullable void (^)(NSError *_Nullable error))completion {
  104. ParsedSetData parsed =
  105. merge ? [_documentReference.firestore().dataConverter parsedMergeData:documentData
  106. fieldMask:nil]
  107. : [_documentReference.firestore().dataConverter parsedSetData:documentData];
  108. _documentReference.SetData(
  109. std::move(parsed).ToMutations(_documentReference.key(), Precondition::None()), completion);
  110. }
  111. - (void)setData:(NSDictionary<NSString *, id> *)documentData
  112. mergeFields:(NSArray<id> *)mergeFields
  113. completion:(nullable void (^)(NSError *_Nullable error))completion {
  114. ParsedSetData parsed = [_documentReference.firestore().dataConverter parsedMergeData:documentData
  115. fieldMask:mergeFields];
  116. _documentReference.SetData(
  117. std::move(parsed).ToMutations(_documentReference.key(), Precondition::None()), completion);
  118. }
  119. - (void)updateData:(NSDictionary<id, id> *)fields {
  120. [self updateData:fields completion:nil];
  121. }
  122. - (void)updateData:(NSDictionary<id, id> *)fields
  123. completion:(nullable void (^)(NSError *_Nullable error))completion {
  124. ParsedUpdateData parsed = [_documentReference.firestore().dataConverter parsedUpdateData:fields];
  125. _documentReference.UpdateData(
  126. std::move(parsed).ToMutations(_documentReference.key(), Precondition::Exists(true)),
  127. completion);
  128. }
  129. - (void)deleteDocument {
  130. [self deleteDocumentWithCompletion:nil];
  131. }
  132. - (void)deleteDocumentWithCompletion:(nullable void (^)(NSError *_Nullable error))completion {
  133. _documentReference.DeleteDocument(completion);
  134. }
  135. - (void)getDocumentWithCompletion:(void (^)(FIRDocumentSnapshot *_Nullable document,
  136. NSError *_Nullable error))completion {
  137. [self getDocumentWithSource:FIRFirestoreSourceDefault completion:completion];
  138. }
  139. - (void)getDocumentWithSource:(FIRFirestoreSource)source
  140. completion:(void (^)(FIRDocumentSnapshot *_Nullable document,
  141. NSError *_Nullable error))completion {
  142. _documentReference.GetDocument(source, completion);
  143. }
  144. - (id<FIRListenerRegistration>)addSnapshotListener:(FIRDocumentSnapshotBlock)listener {
  145. return [self addSnapshotListenerWithIncludeMetadataChanges:NO listener:listener];
  146. }
  147. - (id<FIRListenerRegistration>)
  148. addSnapshotListenerWithIncludeMetadataChanges:(BOOL)includeMetadataChanges
  149. listener:(FIRDocumentSnapshotBlock)listener {
  150. FSTListenOptions *options =
  151. [self internalOptionsForIncludeMetadataChanges:includeMetadataChanges];
  152. return [self addSnapshotListenerInternalWithOptions:options listener:listener];
  153. }
  154. - (id<FIRListenerRegistration>)
  155. addSnapshotListenerInternalWithOptions:(FSTListenOptions *)internalOptions
  156. listener:(FIRDocumentSnapshotBlock)listener {
  157. return _documentReference.AddSnapshotListener(listener, internalOptions);
  158. }
  159. /** Converts the public API options object to the internal options object. */
  160. - (FSTListenOptions *)internalOptionsForIncludeMetadataChanges:(BOOL)includeMetadataChanges {
  161. return [[FSTListenOptions alloc] initWithIncludeQueryMetadataChanges:includeMetadataChanges
  162. includeDocumentMetadataChanges:includeMetadataChanges
  163. waitForSyncWhenOnline:NO];
  164. }
  165. @end
  166. #pragma mark - FIRDocumentReference (Internal)
  167. @implementation FIRDocumentReference (Internal)
  168. + (instancetype)referenceWithPath:(const ResourcePath &)path firestore:(FIRFirestore *)firestore {
  169. if (path.size() % 2 != 0) {
  170. FSTThrowInvalidArgument(@"Invalid document reference. Document references must have an even "
  171. "number of segments, but %s has %zu",
  172. path.CanonicalString().c_str(), path.size());
  173. }
  174. return [FIRDocumentReference referenceWithKey:DocumentKey{path} firestore:firestore];
  175. }
  176. + (instancetype)referenceWithKey:(DocumentKey)key firestore:(FIRFirestore *)firestore {
  177. DocumentReference underlyingReference{firestore, std::move(key)};
  178. return [[FIRDocumentReference alloc] initWithReference:std::move(underlyingReference)];
  179. }
  180. - (const DocumentKey &)key {
  181. return _documentReference.key();
  182. }
  183. @end
  184. NS_ASSUME_NONNULL_END