Skip to content

Commit 220589d

Browse files
authored
Port FIRCollectionReference to C++ (#3126)
Also fix up DocumentReference to use it.
1 parent f39ac87 commit 220589d

18 files changed

+311
-89
lines changed

Firestore/Example/Firestore.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,7 +2442,7 @@
24422442
"${PODS_ROOT}/Target Support Files/Pods-Firestore_Example_iOS/Pods-Firestore_Example_iOS-frameworks.sh",
24432443
"${BUILT_PRODUCTS_DIR}/BoringSSL-GRPC-iOS/openssl_grpc.framework",
24442444
"${BUILT_PRODUCTS_DIR}/GTMSessionFetcher-iOS/GTMSessionFetcher.framework",
2445-
"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
2445+
"${BUILT_PRODUCTS_DIR}/GoogleUtilities-b9437b04/GoogleUtilities.framework",
24462446
"${BUILT_PRODUCTS_DIR}/Protobuf-iOS8.0/Protobuf.framework",
24472447
"${BUILT_PRODUCTS_DIR}/gRPC-C++-iOS/grpcpp.framework",
24482448
"${BUILT_PRODUCTS_DIR}/gRPC-Core-iOS/grpc.framework",
@@ -2947,7 +2947,7 @@
29472947
"${PODS_ROOT}/Target Support Files/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS-frameworks.sh",
29482948
"${BUILT_PRODUCTS_DIR}/BoringSSL-GRPC-iOS/openssl_grpc.framework",
29492949
"${BUILT_PRODUCTS_DIR}/GTMSessionFetcher-iOS/GTMSessionFetcher.framework",
2950-
"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
2950+
"${BUILT_PRODUCTS_DIR}/GoogleUtilities-b9437b04/GoogleUtilities.framework",
29512951
"${BUILT_PRODUCTS_DIR}/Protobuf-iOS8.0/Protobuf.framework",
29522952
"${BUILT_PRODUCTS_DIR}/gRPC-C++-iOS/grpcpp.framework",
29532953
"${BUILT_PRODUCTS_DIR}/gRPC-Core-iOS/grpc.framework",

Firestore/Example/Tests/API/FSTAPIHelpers.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@
8484
}
8585

8686
FIRCollectionReference *FSTTestCollectionRef(const absl::string_view path) {
87-
return [FIRCollectionReference referenceWithPath:testutil::Resource(path)
88-
firestore:FSTTestFirestore()];
87+
return [[FIRCollectionReference alloc] initWithPath:testutil::Resource(path)
88+
firestore:FSTTestFirestore().wrapped];
8989
}
9090

9191
FIRDocumentReference *FSTTestDocRef(const absl::string_view path) {

Firestore/Source/API/FIRCollectionReference+Internal.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,26 @@
1616

1717
#import "FIRCollectionReference.h"
1818

19+
#include <memory>
20+
21+
#include "Firestore/core/src/firebase/firestore/api/collection_reference.h"
1922
#include "Firestore/core/src/firebase/firestore/model/resource_path.h"
2023

24+
namespace api = firebase::firestore::api;
2125
namespace model = firebase::firestore::model;
2226

2327
NS_ASSUME_NONNULL_BEGIN
2428

2529
/** Internal FIRCollectionReference API we don't want exposed in our public header files. */
26-
@interface FIRCollectionReference (Internal)
27-
+ (instancetype)referenceWithPath:(const model::ResourcePath &)path
28-
firestore:(FIRFirestore *)firestore;
30+
@interface FIRCollectionReference (/* Init */)
31+
32+
- (instancetype)initWithReference:(api::CollectionReference &&)reference NS_DESIGNATED_INITIALIZER;
33+
34+
// Mark the super class designated initializer unavailable.
35+
- (instancetype)initWithQuery:(api::Query &&)query NS_UNAVAILABLE;
36+
37+
- (instancetype)initWithPath:(model::ResourcePath)path
38+
firestore:(std::shared_ptr<api::Firestore>)firestore;
2939
@end
3040

3141
NS_ASSUME_NONNULL_END

Firestore/Source/API/FIRCollectionReference.mm

Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,53 +18,37 @@
1818

1919
#include <utility>
2020

21-
#include "Firestore/core/src/firebase/firestore/util/autoid.h"
22-
2321
#import "Firestore/Source/API/FIRDocumentReference+Internal.h"
2422
#import "Firestore/Source/API/FIRFirestore+Internal.h"
2523
#import "Firestore/Source/API/FIRQuery+Internal.h"
24+
#import "Firestore/Source/API/FSTUserDataConverter.h"
2625
#import "Firestore/Source/Core/FSTQuery.h"
2726

27+
#include "Firestore/core/src/firebase/firestore/api/collection_reference.h"
2828
#include "Firestore/core/src/firebase/firestore/api/input_validation.h"
29-
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
3029
#include "Firestore/core/src/firebase/firestore/model/resource_path.h"
31-
#include "Firestore/core/src/firebase/firestore/util/hashing.h"
30+
#include "Firestore/core/src/firebase/firestore/util/error_apple.h"
3231
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
3332

3433
namespace util = firebase::firestore::util;
34+
using firebase::firestore::api::CollectionReference;
35+
using firebase::firestore::api::DocumentReference;
3536
using firebase::firestore::api::ThrowInvalidArgument;
36-
using firebase::firestore::model::DocumentKey;
37+
using firebase::firestore::core::ParsedSetData;
3738
using firebase::firestore::model::ResourcePath;
38-
using firebase::firestore::util::CreateAutoId;
3939

4040
NS_ASSUME_NONNULL_BEGIN
4141

42-
@interface FIRCollectionReference ()
43-
- (instancetype)initWithPath:(const ResourcePath &)path
44-
firestore:(FIRFirestore *)firestore NS_DESIGNATED_INITIALIZER;
45-
46-
// Mark the super class designated initializer unavailable.
47-
- (instancetype)initWithQuery:(api::Query &&)query NS_UNAVAILABLE;
48-
@end
49-
50-
@implementation FIRCollectionReference (Internal)
51-
+ (instancetype)referenceWithPath:(const ResourcePath &)path firestore:(FIRFirestore *)firestore {
52-
return [[FIRCollectionReference alloc] initWithPath:path firestore:firestore];
53-
}
54-
@end
55-
5642
@implementation FIRCollectionReference
5743

58-
- (instancetype)initWithPath:(const ResourcePath &)path firestore:(FIRFirestore *)firestore {
59-
if (path.size() % 2 != 1) {
60-
ThrowInvalidArgument("Invalid collection reference. Collection references must have an odd "
61-
"number of segments, but %s has %s",
62-
path.CanonicalString(), path.size());
63-
}
44+
- (instancetype)initWithReference:(CollectionReference &&)reference {
45+
return [super initWithQuery:std::move(reference)];
46+
}
6447

65-
api::Query query([FSTQuery queryWithPath:path], firestore.wrapped);
66-
self = [super initWithQuery:std::move(query)];
67-
return self;
48+
- (instancetype)initWithPath:(ResourcePath)path
49+
firestore:(std::shared_ptr<api::Firestore>)firestore {
50+
CollectionReference ref(std::move(path), std::move(firestore));
51+
return [self initWithReference:std::move(ref)];
6852
}
6953

7054
// Override the designated initializer from the super class.
@@ -80,43 +64,47 @@ - (BOOL)isEqual:(nullable id)other {
8064
return [self isEqualToReference:other];
8165
}
8266

83-
- (BOOL)isEqualToReference:(nullable FIRCollectionReference *)reference {
84-
if (self == reference) return YES;
85-
if (reference == nil) return NO;
86-
return [self.firestore isEqual:reference.firestore] && [self.query isEqual:reference.query];
67+
- (BOOL)isEqualToReference:(nullable FIRCollectionReference *)otherReference {
68+
if (self == otherReference) return YES;
69+
if (otherReference == nil) return NO;
70+
return self.reference == otherReference.reference;
8771
}
8872

8973
- (NSUInteger)hash {
90-
return util::Hash(self.firestore, self.query);
74+
return self.reference.Hash();
75+
}
76+
77+
- (const CollectionReference &)reference {
78+
// TODO(wilhuff): Use some alternate method for doing this.
79+
//
80+
// Casting from Query& to CollectionReference& when the value is actually a
81+
// Query violates aliasing rules and is technically undefined behavior.
82+
// Nevertheless this works on Clang so this is good enough for now.
83+
return static_cast<const CollectionReference &>(self.apiQuery);
9184
}
9285

9386
- (NSString *)collectionID {
94-
return util::WrapNSString(self.query.path.last_segment());
87+
return util::WrapNSString(self.reference.collection_id());
9588
}
9689

9790
- (FIRDocumentReference *_Nullable)parent {
98-
const ResourcePath parentPath = self.query.path.PopLast();
99-
if (parentPath.empty()) {
91+
absl::optional<DocumentReference> parent = self.reference.parent();
92+
if (!parent) {
10093
return nil;
101-
} else {
102-
DocumentKey key{parentPath};
103-
return [[FIRDocumentReference alloc] initWithKey:std::move(key)
104-
firestore:self.firestore.wrapped];
10594
}
95+
return [[FIRDocumentReference alloc] initWithReference:std::move(*parent)];
10696
}
10797

10898
- (NSString *)path {
109-
return util::WrapNSString(self.query.path.CanonicalString());
99+
return util::WrapNSString(self.reference.path());
110100
}
111101

112102
- (FIRDocumentReference *)documentWithPath:(NSString *)documentPath {
113103
if (!documentPath) {
114104
ThrowInvalidArgument("Document path cannot be nil.");
115105
}
116-
const ResourcePath subPath = ResourcePath::FromString(util::MakeString(documentPath));
117-
ResourcePath path = self.query.path.Append(subPath);
118-
return [[FIRDocumentReference alloc] initWithPath:std::move(path)
119-
firestore:self.firestore.wrapped];
106+
DocumentReference child = self.reference.Document(util::MakeString(documentPath));
107+
return [[FIRDocumentReference alloc] initWithReference:std::move(child)];
120108
}
121109

122110
- (FIRDocumentReference *)addDocumentWithData:(NSDictionary<NSString *, id> *)data {
@@ -126,14 +114,14 @@ - (FIRDocumentReference *)addDocumentWithData:(NSDictionary<NSString *, id> *)da
126114
- (FIRDocumentReference *)addDocumentWithData:(NSDictionary<NSString *, id> *)data
127115
completion:
128116
(nullable void (^)(NSError *_Nullable error))completion {
129-
FIRDocumentReference *docRef = [self documentWithAutoID];
130-
[docRef setData:data completion:completion];
131-
return docRef;
117+
ParsedSetData parsed = [self.firestore.dataConverter parsedSetData:data];
118+
DocumentReference docRef =
119+
self.reference.AddDocument(std::move(parsed), util::MakeCallback(completion));
120+
return [[FIRDocumentReference alloc] initWithReference:std::move(docRef)];
132121
}
133122

134123
- (FIRDocumentReference *)documentWithAutoID {
135-
DocumentKey key{self.query.path.Append(CreateAutoId())};
136-
return [[FIRDocumentReference alloc] initWithKey:std::move(key) firestore:self.firestore.wrapped];
124+
return [[FIRDocumentReference alloc] initWithReference:self.reference.Document()];
137125
}
138126

139127
@end

Firestore/Source/API/FIRDocumentReference.mm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
4747

4848
namespace util = firebase::firestore::util;
49+
using firebase::firestore::api::CollectionReference;
4950
using firebase::firestore::api::DocumentReference;
5051
using firebase::firestore::api::DocumentSnapshot;
5152
using firebase::firestore::api::Firestore;
@@ -118,8 +119,7 @@ - (NSString *)documentID {
118119
}
119120

120121
- (FIRCollectionReference *)parent {
121-
return [FIRCollectionReference referenceWithPath:_documentReference.key().path().PopLast()
122-
firestore:self.firestore];
122+
return [[FIRCollectionReference alloc] initWithReference:_documentReference.Parent()];
123123
}
124124

125125
- (NSString *)path {
@@ -131,9 +131,9 @@ - (FIRCollectionReference *)collectionWithPath:(NSString *)collectionPath {
131131
ThrowInvalidArgument("Collection path cannot be nil.");
132132
}
133133

134-
ResourcePath subPath = ResourcePath::FromString(util::MakeString(collectionPath));
135-
ResourcePath path = _documentReference.key().path().Append(subPath);
136-
return [FIRCollectionReference referenceWithPath:path firestore:self.firestore];
134+
CollectionReference child =
135+
_documentReference.GetCollectionReference(util::MakeString(collectionPath));
136+
return [[FIRCollectionReference alloc] initWithReference:std::move(child)];
137137
}
138138

139139
- (void)setData:(NSDictionary<NSString *, id> *)documentData {

Firestore/Source/API/FIRFirestore.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@
2727

2828
#import "FIRFirestoreSettings+Internal.h"
2929

30+
#import "Firestore/Source/API/FIRCollectionReference+Internal.h"
3031
#import "Firestore/Source/API/FIRDocumentReference+Internal.h"
3132
#import "Firestore/Source/API/FIRFirestore+Internal.h"
3233
#import "Firestore/Source/API/FIRTransaction+Internal.h"
3334
#import "Firestore/Source/API/FIRWriteBatch+Internal.h"
3435
#import "Firestore/Source/API/FSTFirestoreComponent.h"
3536
#import "Firestore/Source/API/FSTUserDataConverter.h"
3637

38+
#include "Firestore/core/src/firebase/firestore/api/collection_reference.h"
3739
#include "Firestore/core/src/firebase/firestore/api/firestore.h"
3840
#include "Firestore/core/src/firebase/firestore/api/input_validation.h"
3941
#include "Firestore/core/src/firebase/firestore/api/write_batch.h"
@@ -156,7 +158,8 @@ - (FIRCollectionReference *)collectionWithPath:(NSString *)collectionPath {
156158
ThrowInvalidArgument("Invalid path (%s). Paths must not contain // in them.", collectionPath);
157159
}
158160

159-
return _firestore->GetCollection(util::MakeString(collectionPath));
161+
return [[FIRCollectionReference alloc]
162+
initWithReference:_firestore->GetCollection(util::MakeString(collectionPath))];
160163
}
161164

162165
- (FIRDocumentReference *)documentWithPath:(NSString *)documentPath {

Firestore/Source/API/FIRQuery+Internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ NS_ASSUME_NONNULL_BEGIN
4040

4141
- (FSTQuery *)query;
4242

43+
- (const api::Query &)apiQuery;
44+
4345
@end
4446

4547
NS_ASSUME_NONNULL_END

Firestore/Source/API/FIRQuery.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,10 @@ - (FSTQuery *)query {
542542
return _query.query();
543543
}
544544

545+
- (const api::Query &)apiQuery {
546+
return _query;
547+
}
548+
545549
@end
546550

547551
NS_ASSUME_NONNULL_END

Firestore/core/src/firebase/firestore/api/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ cc_select(
3939
cc_library(
4040
firebase_firestore_api
4141
SOURCES
42+
collection_reference.h
43+
collection_reference.mm
4244
query_core.h
4345
query_core.mm
4446
settings.cc

0 commit comments

Comments
 (0)