@react-native-firebase/firestore 15.7.1 → 16.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/android/src/main/java/io/invertase/firebase/firestore/UniversalFirebaseFirestoreModule.java +7 -1
- package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreCollectionModule.java +30 -0
- package/ios/RNFBFirestore/RNFBFirestoreCollectionModule.m +37 -0
- package/ios/RNFBFirestore/RNFBFirestoreModule.m +15 -7
- package/lib/FirestoreAggregate.js +52 -0
- package/lib/FirestoreQuery.js +10 -0
- package/lib/index.d.ts +96 -0
- package/lib/version.js +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [16.1.0](https://github.com/invertase/react-native-firebase/compare/v16.0.0...v16.1.0) (2022-10-20)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **firestore, count:** implement AggregateQuery count() on collections ([bd52301](https://github.com/invertase/react-native-firebase/commit/bd52301ad4ef35eeb4dbdab1bc4926db72d40949))
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **firestore, emulator:** avoid double calls to useEmulator ([4e0d188](https://github.com/invertase/react-native-firebase/commit/4e0d188416f4ae8eb176ef024b5698bc892838d5)), closes [#5723](https://github.com/invertase/react-native-firebase/issues/5723)
|
|
15
|
+
|
|
16
|
+
## [16.0.0](https://github.com/invertase/react-native-firebase/compare/v15.7.1...v16.0.0) (2022-10-19)
|
|
17
|
+
|
|
18
|
+
**Note:** Version bump only for package @react-native-firebase/firestore
|
|
19
|
+
|
|
6
20
|
## [15.7.1](https://github.com/invertase/react-native-firebase/compare/v15.7.0...v15.7.1) (2022-10-19)
|
|
7
21
|
|
|
8
22
|
**Note:** Version bump only for package @react-native-firebase/firestore
|
package/android/src/main/java/io/invertase/firebase/firestore/UniversalFirebaseFirestoreModule.java
CHANGED
|
@@ -28,11 +28,14 @@ import com.google.firebase.firestore.LoadBundleTask;
|
|
|
28
28
|
import io.invertase.firebase.common.UniversalFirebaseModule;
|
|
29
29
|
import io.invertase.firebase.common.UniversalFirebasePreferences;
|
|
30
30
|
import java.nio.charset.StandardCharsets;
|
|
31
|
+
import java.util.HashMap;
|
|
31
32
|
import java.util.Map;
|
|
32
33
|
import java.util.Objects;
|
|
33
34
|
|
|
34
35
|
public class UniversalFirebaseFirestoreModule extends UniversalFirebaseModule {
|
|
35
36
|
|
|
37
|
+
private static HashMap<String, String> emulatorConfigs = new HashMap<>();
|
|
38
|
+
|
|
36
39
|
UniversalFirebaseFirestoreModule(Context context, String serviceName) {
|
|
37
40
|
super(context, serviceName);
|
|
38
41
|
}
|
|
@@ -49,7 +52,10 @@ public class UniversalFirebaseFirestoreModule extends UniversalFirebaseModule {
|
|
|
49
52
|
return Tasks.call(
|
|
50
53
|
getExecutor(),
|
|
51
54
|
() -> {
|
|
52
|
-
|
|
55
|
+
if (emulatorConfigs.get(appName) == null) {
|
|
56
|
+
emulatorConfigs.put(appName, "true");
|
|
57
|
+
getFirestoreForApp(appName).useEmulator(host, port);
|
|
58
|
+
}
|
|
53
59
|
return null;
|
|
54
60
|
});
|
|
55
61
|
}
|
|
@@ -148,6 +148,36 @@ public class ReactNativeFirebaseFirestoreCollectionModule extends ReactNativeFir
|
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
@ReactMethod
|
|
152
|
+
public void collectionCount(
|
|
153
|
+
String appName,
|
|
154
|
+
String path,
|
|
155
|
+
String type,
|
|
156
|
+
ReadableArray filters,
|
|
157
|
+
ReadableArray orders,
|
|
158
|
+
ReadableMap options,
|
|
159
|
+
Promise promise) {
|
|
160
|
+
FirebaseFirestore firebaseFirestore = getFirestoreForApp(appName);
|
|
161
|
+
ReactNativeFirebaseFirestoreQuery firestoreQuery =
|
|
162
|
+
new ReactNativeFirebaseFirestoreQuery(
|
|
163
|
+
appName, getQueryForFirestore(firebaseFirestore, path, type), filters, orders, options);
|
|
164
|
+
|
|
165
|
+
AggregateQuery aggregateQuery = firestoreQuery.query.count();
|
|
166
|
+
|
|
167
|
+
aggregateQuery
|
|
168
|
+
.get(AggregateSource.SERVER)
|
|
169
|
+
.addOnCompleteListener(
|
|
170
|
+
task -> {
|
|
171
|
+
if (task.isSuccessful()) {
|
|
172
|
+
WritableMap result = Arguments.createMap();
|
|
173
|
+
result.putDouble("count", Long.valueOf(task.getResult().getCount()).doubleValue());
|
|
174
|
+
promise.resolve(result);
|
|
175
|
+
} else {
|
|
176
|
+
rejectPromiseFirestoreException(promise, task.getException());
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
151
181
|
@ReactMethod
|
|
152
182
|
public void collectionGet(
|
|
153
183
|
String appName,
|
|
@@ -165,6 +165,43 @@ RCT_EXPORT_METHOD(namedQueryGet
|
|
|
165
165
|
}];
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
RCT_EXPORT_METHOD(collectionCount
|
|
169
|
+
: (FIRApp *)firebaseApp
|
|
170
|
+
: (NSString *)path
|
|
171
|
+
: (NSString *)type
|
|
172
|
+
: (NSArray *)filters
|
|
173
|
+
: (NSArray *)orders
|
|
174
|
+
: (NSDictionary *)options
|
|
175
|
+
: (RCTPromiseResolveBlock)resolve
|
|
176
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
177
|
+
FIRFirestore *firestore = [RNFBFirestoreCommon getFirestoreForApp:firebaseApp];
|
|
178
|
+
FIRQuery *query = [RNFBFirestoreCommon getQueryForFirestore:firestore path:path type:type];
|
|
179
|
+
RNFBFirestoreQuery *firestoreQuery = [[RNFBFirestoreQuery alloc] initWithModifiers:firestore
|
|
180
|
+
query:query
|
|
181
|
+
filters:filters
|
|
182
|
+
orders:orders
|
|
183
|
+
options:options];
|
|
184
|
+
|
|
185
|
+
// NOTE: There is only "server" as the source at the moment. So this
|
|
186
|
+
// is unused for the time being. Using "FIRAggregateSourceServer".
|
|
187
|
+
// NSString *source = arguments[@"source"];
|
|
188
|
+
|
|
189
|
+
FIRAggregateQuery *aggregateQuery = [firestoreQuery.query count];
|
|
190
|
+
|
|
191
|
+
[aggregateQuery
|
|
192
|
+
aggregationWithSource:FIRAggregateSourceServer
|
|
193
|
+
completion:^(FIRAggregateQuerySnapshot *_Nullable snapshot,
|
|
194
|
+
NSError *_Nullable error) {
|
|
195
|
+
if (error) {
|
|
196
|
+
[RNFBFirestoreCommon promiseRejectFirestoreException:reject error:error];
|
|
197
|
+
} else {
|
|
198
|
+
NSMutableDictionary *snapshotMap = [NSMutableDictionary dictionary];
|
|
199
|
+
snapshotMap[@"count"] = snapshot.count;
|
|
200
|
+
resolve(snapshotMap);
|
|
201
|
+
}
|
|
202
|
+
}];
|
|
203
|
+
}
|
|
204
|
+
|
|
168
205
|
RCT_EXPORT_METHOD(collectionGet
|
|
169
206
|
: (FIRApp *)firebaseApp
|
|
170
207
|
: (NSString *)path
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
#import "RNFBFirestoreCommon.h"
|
|
21
21
|
#import "RNFBPreferences.h"
|
|
22
22
|
|
|
23
|
+
NSMutableDictionary *emulatorConfigs;
|
|
24
|
+
|
|
23
25
|
@implementation RNFBFirestoreModule
|
|
24
26
|
#pragma mark -
|
|
25
27
|
#pragma mark Module Setup
|
|
@@ -142,13 +144,19 @@ RCT_EXPORT_METHOD(useEmulator
|
|
|
142
144
|
: (FIRApp *)firebaseApp
|
|
143
145
|
: (nonnull NSString *)host
|
|
144
146
|
: (NSInteger)port) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
if (emulatorConfigs == nil) {
|
|
148
|
+
emulatorConfigs = [[NSMutableDictionary alloc] init];
|
|
149
|
+
}
|
|
150
|
+
if (!emulatorConfigs[firebaseApp.name]) {
|
|
151
|
+
FIRFirestore *firestore = [RNFBFirestoreCommon getFirestoreForApp:firebaseApp];
|
|
152
|
+
[firestore useEmulatorWithHost:host port:port];
|
|
153
|
+
emulatorConfigs[firebaseApp.name] = @YES;
|
|
154
|
+
|
|
155
|
+
// It is not sufficient to just use emulator. You have toggle SSL off too.
|
|
156
|
+
FIRFirestoreSettings *settings = firestore.settings;
|
|
157
|
+
settings.sslEnabled = FALSE;
|
|
158
|
+
firestore.settings = settings;
|
|
159
|
+
}
|
|
152
160
|
}
|
|
153
161
|
|
|
154
162
|
RCT_EXPORT_METHOD(waitForPendingWrites
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library 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
|
+
*/
|
|
17
|
+
|
|
18
|
+
export class FirestoreAggregateQuery {
|
|
19
|
+
constructor(firestore, query, collectionPath, modifiers) {
|
|
20
|
+
this._firestore = firestore;
|
|
21
|
+
this._query = query;
|
|
22
|
+
this._collectionPath = collectionPath;
|
|
23
|
+
this._modifiers = modifiers;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get query() {
|
|
27
|
+
return this._query;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get() {
|
|
31
|
+
return this._firestore.native
|
|
32
|
+
.collectionCount(
|
|
33
|
+
this._collectionPath.relativeName,
|
|
34
|
+
this._modifiers.type,
|
|
35
|
+
this._modifiers.filters,
|
|
36
|
+
this._modifiers.orders,
|
|
37
|
+
this._modifiers.options,
|
|
38
|
+
)
|
|
39
|
+
.then(data => new FirestoreAggregateQuerySnapshot(this._query, data));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class FirestoreAggregateQuerySnapshot {
|
|
44
|
+
constructor(query, data) {
|
|
45
|
+
this._query = query;
|
|
46
|
+
this._data = data;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
data() {
|
|
50
|
+
return { count: this._data.count };
|
|
51
|
+
}
|
|
52
|
+
}
|
package/lib/FirestoreQuery.js
CHANGED
|
@@ -26,6 +26,7 @@ import NativeError from '@react-native-firebase/app/lib/internal/NativeFirebaseE
|
|
|
26
26
|
import FirestoreDocumentSnapshot from './FirestoreDocumentSnapshot';
|
|
27
27
|
import FirestoreFieldPath, { fromDotSeparatedString } from './FirestoreFieldPath';
|
|
28
28
|
import FirestoreQuerySnapshot from './FirestoreQuerySnapshot';
|
|
29
|
+
import { FirestoreAggregateQuery } from './FirestoreAggregate';
|
|
29
30
|
import { parseSnapshotArgs } from './utils';
|
|
30
31
|
|
|
31
32
|
let _id = 0;
|
|
@@ -130,6 +131,15 @@ export default class FirestoreQuery {
|
|
|
130
131
|
return modifiers.setFieldsCursor(cursor, allFields);
|
|
131
132
|
}
|
|
132
133
|
|
|
134
|
+
count() {
|
|
135
|
+
return new FirestoreAggregateQuery(
|
|
136
|
+
this._firestore,
|
|
137
|
+
this,
|
|
138
|
+
this._collectionPath,
|
|
139
|
+
this._modifiers,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
133
143
|
endAt(docOrField, ...fields) {
|
|
134
144
|
return new FirestoreQuery(
|
|
135
145
|
this._firestore,
|
package/lib/index.d.ts
CHANGED
|
@@ -840,11 +840,107 @@ export namespace FirebaseFirestoreTypes {
|
|
|
840
840
|
source: 'default' | 'server' | 'cache';
|
|
841
841
|
}
|
|
842
842
|
|
|
843
|
+
/**
|
|
844
|
+
* Represents an aggregation that can be performed by Firestore.
|
|
845
|
+
*/
|
|
846
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
847
|
+
export class AggregateField<T> {
|
|
848
|
+
/** A type string to uniquely identify instances of this class. */
|
|
849
|
+
type = 'AggregateField';
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* The union of all `AggregateField` types that are supported by Firestore.
|
|
854
|
+
*/
|
|
855
|
+
export type AggregateFieldType = AggregateField<number>;
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* A type whose property values are all `AggregateField` objects.
|
|
859
|
+
*/
|
|
860
|
+
export interface AggregateSpec {
|
|
861
|
+
[field: string]: AggregateFieldType;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* A type whose keys are taken from an `AggregateSpec`, and whose values are the
|
|
866
|
+
* result of the aggregation performed by the corresponding `AggregateField`
|
|
867
|
+
* from the input `AggregateSpec`.
|
|
868
|
+
*/
|
|
869
|
+
export type AggregateSpecData<T extends AggregateSpec> = {
|
|
870
|
+
[P in keyof T]: T[P] extends AggregateField<infer U> ? U : never;
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* The results of executing an aggregation query.
|
|
875
|
+
*/
|
|
876
|
+
export interface AggregateQuerySnapshot<T extends AggregateSpec> {
|
|
877
|
+
/**
|
|
878
|
+
* The underlying query over which the aggregations recorded in this
|
|
879
|
+
* `AggregateQuerySnapshot` were performed.
|
|
880
|
+
*/
|
|
881
|
+
get query(): Query<unknown>;
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* Returns the results of the aggregations performed over the underlying
|
|
885
|
+
* query.
|
|
886
|
+
*
|
|
887
|
+
* The keys of the returned object will be the same as those of the
|
|
888
|
+
* `AggregateSpec` object specified to the aggregation method, and the values
|
|
889
|
+
* will be the corresponding aggregation result.
|
|
890
|
+
*
|
|
891
|
+
* @returns The results of the aggregations performed over the underlying
|
|
892
|
+
* query.
|
|
893
|
+
*/
|
|
894
|
+
data(): AggregateSpecData<T>;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* The results of requesting an aggregated query.
|
|
899
|
+
*/
|
|
900
|
+
export interface AggregateQuery<T extends AggregateSpec> {
|
|
901
|
+
/**
|
|
902
|
+
* The underlying query for this instance.
|
|
903
|
+
*/
|
|
904
|
+
get query(): Query<unknown>;
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Executes the query and returns the results as a AggregateQuerySnapshot.
|
|
908
|
+
*
|
|
909
|
+
*
|
|
910
|
+
* #### Example
|
|
911
|
+
*
|
|
912
|
+
* ```js
|
|
913
|
+
* const querySnapshot = await firebase.firestore()
|
|
914
|
+
* .collection('users')
|
|
915
|
+
* .count()
|
|
916
|
+
* .get();
|
|
917
|
+
* ```
|
|
918
|
+
*
|
|
919
|
+
* @param options An object to configure the get behavior.
|
|
920
|
+
*/
|
|
921
|
+
get(): Promise<AggregateQuerySnapshot<T>>;
|
|
922
|
+
}
|
|
923
|
+
|
|
843
924
|
/**
|
|
844
925
|
* A Query refers to a `Query` which you can read or listen to. You can also construct refined `Query` objects by
|
|
845
926
|
* adding filters and ordering.
|
|
846
927
|
*/
|
|
847
928
|
export interface Query<T extends DocumentData = DocumentData> {
|
|
929
|
+
/**
|
|
930
|
+
* Calculates the number of documents in the result set of the given query, without actually downloading
|
|
931
|
+
* the documents.
|
|
932
|
+
*
|
|
933
|
+
* Using this function to count the documents is efficient because only the final count, not the
|
|
934
|
+
* documents' data, is downloaded. This function can even count the documents if the result set
|
|
935
|
+
* would be prohibitively large to download entirely (e.g. thousands of documents).
|
|
936
|
+
*
|
|
937
|
+
* The result received from the server is presented, unaltered, without considering any local state.
|
|
938
|
+
* That is, documents in the local cache are not taken into consideration, neither are local
|
|
939
|
+
* modifications not yet synchronized with the server. Previously-downloaded results, if any,
|
|
940
|
+
* are not used: every request using this source necessarily involves a round trip to the server.
|
|
941
|
+
*/
|
|
942
|
+
count(): AggregateQuery<{ count: AggregateField<number> }>;
|
|
943
|
+
|
|
848
944
|
/**
|
|
849
945
|
* Creates and returns a new Query that ends at the provided document (inclusive). The end
|
|
850
946
|
* position is relative to the order of the query. The document must contain all of the
|
package/lib/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
module.exports = '
|
|
2
|
+
module.exports = '16.1.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-firebase/firestore",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "16.1.0",
|
|
4
4
|
"author": "Invertase <oss@invertase.io> (http://invertase.io)",
|
|
5
5
|
"description": "React Native Firebase - Cloud Firestore is a NoSQL cloud database to store and sync data between your React Native application and Firebase's database. The API matches the Firebase Web SDK whilst taking advantage of the native SDKs performance and offline capabilities.",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"firestore"
|
|
28
28
|
],
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@react-native-firebase/app": "
|
|
30
|
+
"@react-native-firebase/app": "16.1.0"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "f2d1363b89fb046388f8336b08852c1ea0c285f2"
|
|
36
36
|
}
|