@react-native-firebase/firestore 17.4.3 → 17.5.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 +6 -0
- package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreQuery.java +120 -42
- package/ios/RNFBFirestore/RNFBFirestoreQuery.m +81 -16
- package/lib/FirestoreFilter.js +151 -0
- package/lib/FirestoreQuery.js +58 -40
- package/lib/FirestoreQueryModifiers.js +67 -37
- package/lib/FirestoreStatics.js +2 -1
- package/lib/index.d.ts +41 -0
- package/lib/version.js +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
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
|
+
## [17.5.0](https://github.com/invertase/react-native-firebase/compare/v17.4.3...v17.5.0) (2023-05-11)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **firestore:** Firestore `Filter` instance. Use `Filter`, `Filter.or()` & `Filter.and()` in Firestore queries. ([#7045](https://github.com/invertase/react-native-firebase/issues/7045)) ([f7ec3d1](https://github.com/invertase/react-native-firebase/commit/f7ec3d1970f4fa8cc9752bb3cd8f1550b2a457c5))
|
|
11
|
+
|
|
6
12
|
### [17.4.3](https://github.com/invertase/react-native-firebase/compare/v17.4.2...v17.4.3) (2023-04-26)
|
|
7
13
|
|
|
8
14
|
**Note:** Version bump only for package @react-native-firebase/firestore
|
|
@@ -26,6 +26,7 @@ import com.facebook.react.bridge.WritableMap;
|
|
|
26
26
|
import com.google.android.gms.tasks.Task;
|
|
27
27
|
import com.google.android.gms.tasks.Tasks;
|
|
28
28
|
import com.google.firebase.firestore.FieldPath;
|
|
29
|
+
import com.google.firebase.firestore.Filter;
|
|
29
30
|
import com.google.firebase.firestore.Query;
|
|
30
31
|
import com.google.firebase.firestore.QuerySnapshot;
|
|
31
32
|
import com.google.firebase.firestore.Source;
|
|
@@ -65,62 +66,139 @@ public class ReactNativeFirebaseFirestoreQuery {
|
|
|
65
66
|
for (int i = 0; i < filters.size(); i++) {
|
|
66
67
|
ReadableMap filter = filters.getMap(i);
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
if (filter.hasKey("fieldPath")) {
|
|
70
|
+
ArrayList<Object> fieldPathArray =
|
|
71
|
+
Objects.requireNonNull(Objects.requireNonNull(filter).getArray("fieldPath"))
|
|
72
|
+
.toArrayList();
|
|
73
|
+
String[] segmentArray = (String[]) fieldPathArray.toArray(new String[0]);
|
|
74
|
+
|
|
75
|
+
FieldPath fieldPath = FieldPath.of(Objects.requireNonNull(segmentArray));
|
|
76
|
+
String operator = filter.getString("operator");
|
|
77
|
+
ReadableArray arrayValue = filter.getArray("value");
|
|
78
|
+
Object value = parseTypeMap(query.getFirestore(), Objects.requireNonNull(arrayValue));
|
|
79
|
+
|
|
80
|
+
switch (Objects.requireNonNull(operator)) {
|
|
81
|
+
case "EQUAL":
|
|
82
|
+
query = query.whereEqualTo(Objects.requireNonNull(fieldPath), value);
|
|
83
|
+
break;
|
|
84
|
+
case "NOT_EQUAL":
|
|
85
|
+
query = query.whereNotEqualTo(Objects.requireNonNull(fieldPath), value);
|
|
86
|
+
break;
|
|
87
|
+
case "GREATER_THAN":
|
|
88
|
+
query =
|
|
89
|
+
query.whereGreaterThan(
|
|
90
|
+
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
91
|
+
break;
|
|
92
|
+
case "GREATER_THAN_OR_EQUAL":
|
|
93
|
+
query =
|
|
94
|
+
query.whereGreaterThanOrEqualTo(
|
|
95
|
+
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
96
|
+
break;
|
|
97
|
+
case "LESS_THAN":
|
|
98
|
+
query =
|
|
99
|
+
query.whereLessThan(
|
|
100
|
+
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
101
|
+
break;
|
|
102
|
+
case "LESS_THAN_OR_EQUAL":
|
|
103
|
+
query =
|
|
104
|
+
query.whereLessThanOrEqualTo(
|
|
105
|
+
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
106
|
+
break;
|
|
107
|
+
case "ARRAY_CONTAINS":
|
|
108
|
+
query =
|
|
109
|
+
query.whereArrayContains(
|
|
110
|
+
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
111
|
+
break;
|
|
112
|
+
case "ARRAY_CONTAINS_ANY":
|
|
113
|
+
query =
|
|
114
|
+
query.whereArrayContainsAny(
|
|
115
|
+
Objects.requireNonNull(fieldPath),
|
|
116
|
+
Objects.requireNonNull((List<Object>) value));
|
|
117
|
+
break;
|
|
118
|
+
case "IN":
|
|
119
|
+
query =
|
|
120
|
+
query.whereIn(
|
|
121
|
+
Objects.requireNonNull(fieldPath),
|
|
122
|
+
Objects.requireNonNull((List<Object>) value));
|
|
123
|
+
break;
|
|
124
|
+
case "NOT_IN":
|
|
125
|
+
query =
|
|
126
|
+
query.whereNotIn(
|
|
127
|
+
Objects.requireNonNull(fieldPath),
|
|
128
|
+
Objects.requireNonNull((List<Object>) value));
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
} else if (filter.hasKey("operator") && filter.hasKey("queries")) {
|
|
132
|
+
query = query.where(applyFilterQueries(filter));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private Filter applyFilterQueries(ReadableMap filter) {
|
|
138
|
+
if (filter.hasKey("fieldPath")) {
|
|
139
|
+
String operator =
|
|
140
|
+
(String) Objects.requireNonNull(Objects.requireNonNull(filter).getString("operator"));
|
|
141
|
+
ReadableMap fieldPathMap = Objects.requireNonNull(filter.getMap("fieldPath"));
|
|
142
|
+
ReadableArray segments = Objects.requireNonNull(fieldPathMap.getArray("_segments"));
|
|
143
|
+
int arraySize = segments.size();
|
|
144
|
+
String[] segmentArray = new String[arraySize];
|
|
70
145
|
|
|
71
|
-
|
|
72
|
-
|
|
146
|
+
for (int i = 0; i < arraySize; i++) {
|
|
147
|
+
segmentArray[i] = segments.getString(i);
|
|
148
|
+
}
|
|
149
|
+
FieldPath fieldPath = FieldPath.of(segmentArray);
|
|
73
150
|
ReadableArray arrayValue = filter.getArray("value");
|
|
151
|
+
|
|
74
152
|
Object value = parseTypeMap(query.getFirestore(), Objects.requireNonNull(arrayValue));
|
|
75
153
|
|
|
76
|
-
switch (
|
|
154
|
+
switch (operator) {
|
|
77
155
|
case "EQUAL":
|
|
78
|
-
|
|
79
|
-
break;
|
|
156
|
+
return Filter.equalTo(fieldPath, value);
|
|
80
157
|
case "NOT_EQUAL":
|
|
81
|
-
|
|
82
|
-
break;
|
|
83
|
-
case "GREATER_THAN":
|
|
84
|
-
query =
|
|
85
|
-
query.whereGreaterThan(
|
|
86
|
-
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
87
|
-
break;
|
|
88
|
-
case "GREATER_THAN_OR_EQUAL":
|
|
89
|
-
query =
|
|
90
|
-
query.whereGreaterThanOrEqualTo(
|
|
91
|
-
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
92
|
-
break;
|
|
158
|
+
return Filter.notEqualTo(fieldPath, value);
|
|
93
159
|
case "LESS_THAN":
|
|
94
|
-
|
|
95
|
-
query.whereLessThan(Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
96
|
-
break;
|
|
160
|
+
return Filter.lessThan(fieldPath, value);
|
|
97
161
|
case "LESS_THAN_OR_EQUAL":
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
162
|
+
return Filter.lessThanOrEqualTo(fieldPath, value);
|
|
163
|
+
case "GREATER_THAN":
|
|
164
|
+
return Filter.greaterThan(fieldPath, value);
|
|
165
|
+
case "GREATER_THAN_OR_EQUAL":
|
|
166
|
+
return Filter.greaterThanOrEqualTo(fieldPath, value);
|
|
102
167
|
case "ARRAY_CONTAINS":
|
|
103
|
-
|
|
104
|
-
query.whereArrayContains(
|
|
105
|
-
Objects.requireNonNull(fieldPath), Objects.requireNonNull(value));
|
|
106
|
-
break;
|
|
168
|
+
return Filter.arrayContains(fieldPath, value);
|
|
107
169
|
case "ARRAY_CONTAINS_ANY":
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
Objects.requireNonNull(fieldPath), Objects.requireNonNull((List<Object>) value));
|
|
111
|
-
break;
|
|
170
|
+
assert value != null;
|
|
171
|
+
return Filter.arrayContainsAny(fieldPath, (List<?>) value);
|
|
112
172
|
case "IN":
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Objects.requireNonNull(fieldPath), Objects.requireNonNull((List<Object>) value));
|
|
116
|
-
break;
|
|
173
|
+
assert value != null;
|
|
174
|
+
return Filter.inArray(fieldPath, (List<?>) value);
|
|
117
175
|
case "NOT_IN":
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
176
|
+
assert value != null;
|
|
177
|
+
return Filter.notInArray(fieldPath, (List<?>) value);
|
|
178
|
+
default:
|
|
179
|
+
throw new Error("Invalid operator");
|
|
122
180
|
}
|
|
123
181
|
}
|
|
182
|
+
|
|
183
|
+
String operator = Objects.requireNonNull(filter).getString("operator");
|
|
184
|
+
ReadableArray queries =
|
|
185
|
+
Objects.requireNonNull(Objects.requireNonNull(filter).getArray("queries"));
|
|
186
|
+
ArrayList<Filter> parsedFilters = new ArrayList<>();
|
|
187
|
+
int arraySize = queries.size();
|
|
188
|
+
for (int i = 0; i < arraySize; i++) {
|
|
189
|
+
ReadableMap map = queries.getMap(i);
|
|
190
|
+
parsedFilters.add(applyFilterQueries(map));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (operator.equals("AND")) {
|
|
194
|
+
return Filter.and(parsedFilters.toArray(new Filter[0]));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (operator.equals("OR")) {
|
|
198
|
+
return Filter.or(parsedFilters.toArray(new Filter[0]));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
throw new Error("Missing 'Filter' instance return");
|
|
124
202
|
}
|
|
125
203
|
|
|
126
204
|
private void applyOrders(ReadableArray orders) {
|
|
@@ -51,33 +51,98 @@
|
|
|
51
51
|
|
|
52
52
|
- (void)applyFilters {
|
|
53
53
|
for (NSDictionary *filter in _filters) {
|
|
54
|
-
|
|
54
|
+
if (filter[@"fieldPath"]) {
|
|
55
|
+
NSArray *fieldPathArray = filter[@"fieldPath"];
|
|
56
|
+
|
|
57
|
+
FIRFieldPath *fieldPath = [[FIRFieldPath alloc] initWithFields:fieldPathArray];
|
|
58
|
+
NSString *operator= filter[@"operator"];
|
|
59
|
+
id value = [RNFBFirestoreSerialize parseTypeMap:_firestore typeMap:filter[@"value"]];
|
|
60
|
+
if ([operator isEqualToString:@"EQUAL"]) {
|
|
61
|
+
_query = [_query queryWhereFieldPath:fieldPath isEqualTo:value];
|
|
62
|
+
} else if ([operator isEqualToString:@"NOT_EQUAL"]) {
|
|
63
|
+
_query = [_query queryWhereFieldPath:fieldPath isNotEqualTo:value];
|
|
64
|
+
} else if ([operator isEqualToString:@"GREATER_THAN"]) {
|
|
65
|
+
_query = [_query queryWhereFieldPath:fieldPath isGreaterThan:value];
|
|
66
|
+
} else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) {
|
|
67
|
+
_query = [_query queryWhereFieldPath:fieldPath isGreaterThanOrEqualTo:value];
|
|
68
|
+
} else if ([operator isEqualToString:@"LESS_THAN"]) {
|
|
69
|
+
_query = [_query queryWhereFieldPath:fieldPath isLessThan:value];
|
|
70
|
+
} else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) {
|
|
71
|
+
_query = [_query queryWhereFieldPath:fieldPath isLessThanOrEqualTo:value];
|
|
72
|
+
} else if ([operator isEqualToString:@"ARRAY_CONTAINS"]) {
|
|
73
|
+
_query = [_query queryWhereFieldPath:fieldPath arrayContains:value];
|
|
74
|
+
} else if ([operator isEqualToString:@"IN"]) {
|
|
75
|
+
_query = [_query queryWhereFieldPath:fieldPath in:value];
|
|
76
|
+
} else if ([operator isEqualToString:@"ARRAY_CONTAINS_ANY"]) {
|
|
77
|
+
_query = [_query queryWhereFieldPath:fieldPath arrayContainsAny:value];
|
|
78
|
+
} else if ([operator isEqualToString:@"NOT_IN"]) {
|
|
79
|
+
_query = [_query queryWhereFieldPath:fieldPath notIn:value];
|
|
80
|
+
}
|
|
81
|
+
} else if (filter[@"operator"] && filter[@"queries"]) {
|
|
82
|
+
// Filter query
|
|
83
|
+
FIRFilter *generatedFilter = [self _applyFilterQueries:filter];
|
|
84
|
+
_query = [_query queryWhereFilter:generatedFilter];
|
|
85
|
+
} else {
|
|
86
|
+
@throw
|
|
87
|
+
[NSException exceptionWithName:@"InvalidOperator"
|
|
88
|
+
reason:@"The correct signature for a filter has not been parsed"
|
|
89
|
+
userInfo:nil];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
- (FIRFilter *)_applyFilterQueries:(NSDictionary<NSString *, id> *)map {
|
|
95
|
+
if ([map objectForKey:@"fieldPath"]) {
|
|
96
|
+
NSString *operator= map[@"operator"];
|
|
97
|
+
NSArray *fieldPathArray = map[@"fieldPath"][@"_segments"];
|
|
98
|
+
|
|
55
99
|
FIRFieldPath *fieldPath = [[FIRFieldPath alloc] initWithFields:fieldPathArray];
|
|
56
|
-
|
|
57
|
-
id value = [RNFBFirestoreSerialize parseTypeMap:_firestore typeMap:filter[@"value"]];
|
|
100
|
+
id value = [RNFBFirestoreSerialize parseTypeMap:_firestore typeMap:map[@"value"]];
|
|
58
101
|
|
|
59
102
|
if ([operator isEqualToString:@"EQUAL"]) {
|
|
60
|
-
|
|
103
|
+
return [FIRFilter filterWhereFieldPath:fieldPath isEqualTo:value];
|
|
61
104
|
} else if ([operator isEqualToString:@"NOT_EQUAL"]) {
|
|
62
|
-
|
|
63
|
-
} else if ([operator isEqualToString:@"GREATER_THAN"]) {
|
|
64
|
-
_query = [_query queryWhereFieldPath:fieldPath isGreaterThan:value];
|
|
65
|
-
} else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) {
|
|
66
|
-
_query = [_query queryWhereFieldPath:fieldPath isGreaterThanOrEqualTo:value];
|
|
105
|
+
return [FIRFilter filterWhereFieldPath:fieldPath isNotEqualTo:value];
|
|
67
106
|
} else if ([operator isEqualToString:@"LESS_THAN"]) {
|
|
68
|
-
|
|
107
|
+
return [FIRFilter filterWhereFieldPath:fieldPath isLessThan:value];
|
|
69
108
|
} else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) {
|
|
70
|
-
|
|
109
|
+
return [FIRFilter filterWhereFieldPath:fieldPath isLessThanOrEqualTo:value];
|
|
110
|
+
} else if ([operator isEqualToString:@"GREATER_THAN"]) {
|
|
111
|
+
return [FIRFilter filterWhereFieldPath:fieldPath isGreaterThan:value];
|
|
112
|
+
} else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) {
|
|
113
|
+
return [FIRFilter filterWhereFieldPath:fieldPath isGreaterThanOrEqualTo:value];
|
|
71
114
|
} else if ([operator isEqualToString:@"ARRAY_CONTAINS"]) {
|
|
72
|
-
|
|
73
|
-
} else if ([operator isEqualToString:@"IN"]) {
|
|
74
|
-
_query = [_query queryWhereFieldPath:fieldPath in:value];
|
|
115
|
+
return [FIRFilter filterWhereFieldPath:fieldPath arrayContains:value];
|
|
75
116
|
} else if ([operator isEqualToString:@"ARRAY_CONTAINS_ANY"]) {
|
|
76
|
-
|
|
117
|
+
return [FIRFilter filterWhereFieldPath:fieldPath arrayContainsAny:value];
|
|
118
|
+
} else if ([operator isEqualToString:@"IN"]) {
|
|
119
|
+
return [FIRFilter filterWhereFieldPath:fieldPath in:value];
|
|
77
120
|
} else if ([operator isEqualToString:@"NOT_IN"]) {
|
|
78
|
-
|
|
121
|
+
return [FIRFilter filterWhereFieldPath:fieldPath notIn:value];
|
|
122
|
+
} else {
|
|
123
|
+
@throw [NSException exceptionWithName:@"InvalidOperator"
|
|
124
|
+
reason:@"Invalid operator"
|
|
125
|
+
userInfo:nil];
|
|
79
126
|
}
|
|
80
127
|
}
|
|
128
|
+
|
|
129
|
+
NSString *op = map[@"operator"];
|
|
130
|
+
NSArray<NSDictionary<NSString *, id> *> *queries = map[@"queries"];
|
|
131
|
+
NSMutableArray<FIRFilter *> *parsedFilters = [NSMutableArray array];
|
|
132
|
+
|
|
133
|
+
for (NSDictionary *query in queries) {
|
|
134
|
+
[parsedFilters addObject:[self _applyFilterQueries:query]];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if ([op isEqual:@"AND"]) {
|
|
138
|
+
return [FIRFilter andFilterWithFilters:parsedFilters];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if ([op isEqualToString:@"OR"]) {
|
|
142
|
+
return [FIRFilter orFilterWithFilters:parsedFilters];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@throw [NSException exceptionWithName:@"InvalidOperator" reason:@"Invalid operator" userInfo:nil];
|
|
81
146
|
}
|
|
82
147
|
|
|
83
148
|
- (void)applyOrders {
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { isString, isNull, isUndefined, isArray } from '@react-native-firebase/app/lib/common';
|
|
2
|
+
import { fromDotSeparatedString } from './FirestoreFieldPath';
|
|
3
|
+
import { generateNativeData } from './utils/serialize';
|
|
4
|
+
import { OPERATORS } from './FirestoreQueryModifiers';
|
|
5
|
+
const AND_QUERY = 'AND';
|
|
6
|
+
const OR_QUERY = 'OR';
|
|
7
|
+
|
|
8
|
+
export function Filter(fieldPath, operator, value) {
|
|
9
|
+
return new _Filter(fieldPath, operator, value);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function _Filter(fieldPath, operator, value, filterOperator, queries) {
|
|
13
|
+
if ([AND_QUERY, OR_QUERY].includes(filterOperator)) {
|
|
14
|
+
// AND or OR Filter (list of Filters)
|
|
15
|
+
this.operator = filterOperator;
|
|
16
|
+
this.queries = queries;
|
|
17
|
+
|
|
18
|
+
this._toMap = function _toMap() {
|
|
19
|
+
return {
|
|
20
|
+
operator: this.operator,
|
|
21
|
+
queries: this.queries.map(query => query._toMap()),
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return this;
|
|
26
|
+
} else {
|
|
27
|
+
// Filter
|
|
28
|
+
this.fieldPath = fieldPath;
|
|
29
|
+
this.operator = operator;
|
|
30
|
+
this.value = value;
|
|
31
|
+
|
|
32
|
+
this._toMap = function _toMap() {
|
|
33
|
+
return {
|
|
34
|
+
fieldPath: this.fieldPath,
|
|
35
|
+
operator: this.operator,
|
|
36
|
+
value: this.value,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Filter.and = function and(...queries) {
|
|
45
|
+
if (queries.length > 10 || queries.length < 2) {
|
|
46
|
+
throw new Error(`Expected 2-10 instances of Filter, but got ${queries.length} Filters`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const validateFilters = queries.every(filter => filter instanceof _Filter);
|
|
50
|
+
|
|
51
|
+
if (!validateFilters) {
|
|
52
|
+
throw new Error('Expected every argument to be an instance of Filter');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return new _Filter(null, null, null, AND_QUERY, queries);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
function hasOrOperator(obj) {
|
|
59
|
+
return obj.operator === 'OR' || (Array.isArray(obj.queries) && obj.queries.some(hasOrOperator));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Filter.or = function or(...queries) {
|
|
63
|
+
if (queries.length > 10 || queries.length < 2) {
|
|
64
|
+
throw new Error(`Expected 2-10 instances of Filter, but got ${queries.length} Filters`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const validateFilters = queries.every(filter => filter instanceof _Filter);
|
|
68
|
+
|
|
69
|
+
if (!validateFilters) {
|
|
70
|
+
throw new Error('Expected every argument to be an instance of Filter');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const hasOr = queries.some(hasOrOperator);
|
|
74
|
+
|
|
75
|
+
if (hasOr) {
|
|
76
|
+
throw new Error('OR Filters with nested OR Filters are not supported');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return new _Filter(null, null, null, OR_QUERY, queries);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
function mapFieldQuery({ fieldPath, operator, value, queries }, modifiers) {
|
|
83
|
+
if (operator === AND_QUERY || operator === OR_QUERY) {
|
|
84
|
+
return {
|
|
85
|
+
operator,
|
|
86
|
+
queries: queries.map(filter => mapFieldQuery(filter, modifiers)),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let path;
|
|
91
|
+
if (isString(fieldPath)) {
|
|
92
|
+
try {
|
|
93
|
+
path = fromDotSeparatedString(fieldPath);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
throw new Error(`first argument of Filter(*,_ , _) 'fieldPath' ${e.message}.`);
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
path = fieldPath;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!modifiers.isValidOperator(operator)) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
"second argument of Filter(*,_ , _) 'opStr' is invalid. Expected one of '==', '>', '>=', '<', '<=', '!=', 'array-contains', 'not-in', 'array-contains-any' or 'in'.",
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (isUndefined(value)) {
|
|
108
|
+
throw new Error("third argument of Filter(*,_ , _) 'value' argument expected.");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (
|
|
112
|
+
isNull(value) &&
|
|
113
|
+
!modifiers.isEqualOperator(operator) &&
|
|
114
|
+
!modifiers.isNotEqualOperator(operator)
|
|
115
|
+
) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
"third argument of Filter(*,_ , _) 'value' is invalid. You can only perform equals comparisons on null",
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (modifiers.isInOperator(operator)) {
|
|
122
|
+
if (!isArray(value) || !value.length) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`third argument of Filter(*,_ , _) 'value' is invalid. A non-empty array is required for '${operator}' filters.`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (value.length > 10) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`third argument of Filter(*,_ , _) 'value' is invalid. '${operator}' filters support a maximum of 10 elements in the value array.`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
fieldPath: path,
|
|
137
|
+
operator: OPERATORS[operator],
|
|
138
|
+
value: generateNativeData(value, true),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function generateFilters(filter, modifiers) {
|
|
143
|
+
const filterMap = filter._toMap();
|
|
144
|
+
|
|
145
|
+
const queriesMaps = filterMap.queries.map(filter => mapFieldQuery(filter, modifiers));
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
operator: filterMap.operator,
|
|
149
|
+
queries: queriesMaps,
|
|
150
|
+
};
|
|
151
|
+
}
|
package/lib/FirestoreQuery.js
CHANGED
|
@@ -28,6 +28,7 @@ import FirestoreDocumentSnapshot from './FirestoreDocumentSnapshot';
|
|
|
28
28
|
import FirestoreFieldPath, { fromDotSeparatedString } from './FirestoreFieldPath';
|
|
29
29
|
import FirestoreQuerySnapshot from './FirestoreQuerySnapshot';
|
|
30
30
|
import { parseSnapshotArgs } from './utils';
|
|
31
|
+
import { _Filter, generateFilters } from './FirestoreFilter';
|
|
31
32
|
|
|
32
33
|
let _id = 0;
|
|
33
34
|
|
|
@@ -406,62 +407,79 @@ export default class FirestoreQuery {
|
|
|
406
407
|
);
|
|
407
408
|
}
|
|
408
409
|
|
|
409
|
-
where(
|
|
410
|
-
if (
|
|
410
|
+
where(fieldPathOrFilter, opStr, value) {
|
|
411
|
+
if (
|
|
412
|
+
!isString(fieldPathOrFilter) &&
|
|
413
|
+
!(fieldPathOrFilter instanceof FirestoreFieldPath) &&
|
|
414
|
+
!(fieldPathOrFilter instanceof _Filter)
|
|
415
|
+
) {
|
|
411
416
|
throw new Error(
|
|
412
|
-
"firebase.firestore().collection().where(*) 'fieldPath' must be a string or instance of
|
|
417
|
+
"firebase.firestore().collection().where(*) 'fieldPath' must be a string, instance of FieldPath or instance of Filter.",
|
|
413
418
|
);
|
|
414
419
|
}
|
|
415
420
|
|
|
416
|
-
let
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
} catch (e) {
|
|
422
|
-
throw new Error(`firebase.firestore().collection().where(*) 'fieldPath' ${e.message}.`);
|
|
423
|
-
}
|
|
421
|
+
let modifiers;
|
|
422
|
+
if (fieldPathOrFilter instanceof _Filter && fieldPathOrFilter.queries) {
|
|
423
|
+
//AND or OR filter
|
|
424
|
+
const filters = generateFilters(fieldPathOrFilter, this._modifiers);
|
|
425
|
+
modifiers = this._modifiers._copy().filterWhere(filters);
|
|
424
426
|
} else {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
427
|
+
if (fieldPathOrFilter instanceof _Filter) {
|
|
428
|
+
// Standard Filter. Usual path.
|
|
429
|
+
opStr = fieldPathOrFilter.operator;
|
|
430
|
+
value = fieldPathOrFilter.value;
|
|
431
|
+
fieldPathOrFilter = fieldPathOrFilter.fieldPath;
|
|
432
|
+
}
|
|
433
|
+
let path;
|
|
433
434
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
435
|
+
if (isString(fieldPathOrFilter)) {
|
|
436
|
+
try {
|
|
437
|
+
path = fromDotSeparatedString(fieldPathOrFilter);
|
|
438
|
+
} catch (e) {
|
|
439
|
+
throw new Error(`firebase.firestore().collection().where(*) 'fieldPath' ${e.message}.`);
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
path = fieldPathOrFilter;
|
|
443
|
+
}
|
|
439
444
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
throw new Error(
|
|
446
|
-
"firebase.firestore().collection().where(_, _, *) 'value' is invalid. You can only perform equals comparisons on null",
|
|
447
|
-
);
|
|
448
|
-
}
|
|
445
|
+
if (!this._modifiers.isValidOperator(opStr)) {
|
|
446
|
+
throw new Error(
|
|
447
|
+
"firebase.firestore().collection().where(_, *) 'opStr' is invalid. Expected one of '==', '>', '>=', '<', '<=', '!=', 'array-contains', 'not-in', 'array-contains-any' or 'in'.",
|
|
448
|
+
);
|
|
449
|
+
}
|
|
449
450
|
|
|
450
|
-
|
|
451
|
-
if (!isArray(value) || !value.length) {
|
|
451
|
+
if (isUndefined(value)) {
|
|
452
452
|
throw new Error(
|
|
453
|
-
|
|
453
|
+
"firebase.firestore().collection().where(_, _, *) 'value' argument expected.",
|
|
454
454
|
);
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
-
if (
|
|
457
|
+
if (
|
|
458
|
+
isNull(value) &&
|
|
459
|
+
!this._modifiers.isEqualOperator(opStr) &&
|
|
460
|
+
!this._modifiers.isNotEqualOperator(opStr)
|
|
461
|
+
) {
|
|
458
462
|
throw new Error(
|
|
459
|
-
|
|
463
|
+
"firebase.firestore().collection().where(_, _, *) 'value' is invalid. You can only perform equals comparisons on null",
|
|
460
464
|
);
|
|
461
465
|
}
|
|
462
|
-
}
|
|
463
466
|
|
|
464
|
-
|
|
467
|
+
if (this._modifiers.isInOperator(opStr)) {
|
|
468
|
+
if (!isArray(value) || !value.length) {
|
|
469
|
+
throw new Error(
|
|
470
|
+
`firebase.firestore().collection().where(_, _, *) 'value' is invalid. A non-empty array is required for '${opStr}' filters.`,
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (value.length > 10) {
|
|
475
|
+
throw new Error(
|
|
476
|
+
`firebase.firestore().collection().where(_, _, *) 'value' is invalid. '${opStr}' filters support a maximum of 10 elements in the value array.`,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
modifiers = this._modifiers._copy().where(path, opStr, value);
|
|
482
|
+
}
|
|
465
483
|
|
|
466
484
|
try {
|
|
467
485
|
modifiers.validateWhere();
|
|
@@ -19,7 +19,7 @@ import { isNumber } from '@react-native-firebase/app/lib/common';
|
|
|
19
19
|
import FirestoreFieldPath, { DOCUMENT_ID } from './FirestoreFieldPath';
|
|
20
20
|
import { buildNativeArray, generateNativeData } from './utils/serialize';
|
|
21
21
|
|
|
22
|
-
const OPERATORS = {
|
|
22
|
+
export const OPERATORS = {
|
|
23
23
|
'==': 'EQUAL',
|
|
24
24
|
'>': 'GREATER_THAN',
|
|
25
25
|
'>=': 'GREATER_THAN_OR_EQUAL',
|
|
@@ -57,6 +57,14 @@ export default class FirestoreQueryModifiers {
|
|
|
57
57
|
this._startAfter = undefined;
|
|
58
58
|
this._endAt = undefined;
|
|
59
59
|
this._endBefore = undefined;
|
|
60
|
+
|
|
61
|
+
// Pulled out of function to preserve their state
|
|
62
|
+
this.hasInequality = false;
|
|
63
|
+
this.hasNotEqual = false;
|
|
64
|
+
this.hasArrayContains = false;
|
|
65
|
+
this.hasArrayContainsAny = false;
|
|
66
|
+
this.hasIn = false;
|
|
67
|
+
this.hasNotIn = false;
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
_copy() {
|
|
@@ -221,118 +229,129 @@ export default class FirestoreQueryModifiers {
|
|
|
221
229
|
return this;
|
|
222
230
|
}
|
|
223
231
|
|
|
232
|
+
filterWhere(filter) {
|
|
233
|
+
this._filters = this._filters.concat(filter);
|
|
234
|
+
return this;
|
|
235
|
+
}
|
|
236
|
+
|
|
224
237
|
validateWhere() {
|
|
225
|
-
|
|
226
|
-
|
|
238
|
+
if (this._filters.length > 0) {
|
|
239
|
+
this._filterCheck(this._filters);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
_filterCheck(filters) {
|
|
244
|
+
for (let i = 0; i < filters.length; i++) {
|
|
245
|
+
const filter = filters[i];
|
|
246
|
+
|
|
247
|
+
if (filter.queries) {
|
|
248
|
+
// Recursively check sub-queries for Filters
|
|
249
|
+
this._filterCheck(filter.queries);
|
|
250
|
+
// If it is a Filter query, skip the rest of the loop
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
227
253
|
|
|
228
|
-
for (let i = 0; i < this._filters.length; i++) {
|
|
229
|
-
const filter = this._filters[i];
|
|
230
254
|
// Skip if no inequality
|
|
231
255
|
if (!INEQUALITY[filter.operator]) {
|
|
232
256
|
continue;
|
|
233
257
|
}
|
|
234
258
|
|
|
235
259
|
if (filter.operator === OPERATORS['!=']) {
|
|
236
|
-
if (hasNotEqual) {
|
|
260
|
+
if (this.hasNotEqual) {
|
|
237
261
|
throw new Error("Invalid query. You cannot use more than one '!=' inequality filter.");
|
|
238
262
|
}
|
|
239
263
|
//needs to set hasNotEqual = true before setting first hasInequality = filter. It is used in a condition check later
|
|
240
|
-
hasNotEqual = true;
|
|
264
|
+
this.hasNotEqual = true;
|
|
241
265
|
}
|
|
242
266
|
|
|
243
267
|
// Set the first inequality
|
|
244
|
-
if (!hasInequality) {
|
|
245
|
-
hasInequality = filter;
|
|
268
|
+
if (!this.hasInequality) {
|
|
269
|
+
this.hasInequality = filter;
|
|
246
270
|
continue;
|
|
247
271
|
}
|
|
248
272
|
|
|
249
273
|
// Check the set value is the same as the new one
|
|
250
|
-
if (INEQUALITY[filter.operator] && hasInequality) {
|
|
251
|
-
if (hasInequality.fieldPath._toPath() !== filter.fieldPath._toPath()) {
|
|
274
|
+
if (INEQUALITY[filter.operator] && this.hasInequality) {
|
|
275
|
+
if (this.hasInequality.fieldPath._toPath() !== filter.fieldPath._toPath()) {
|
|
252
276
|
throw new Error(
|
|
253
|
-
`Invalid query. All where filters with an inequality (<, <=, >, != or >=) must be on the same field. But you have inequality filters on '${hasInequality.fieldPath._toPath()}' and '${filter.fieldPath._toPath()}'`,
|
|
277
|
+
`Invalid query. All where filters with an inequality (<, <=, >, != or >=) must be on the same field. But you have inequality filters on '${this.hasInequality.fieldPath._toPath()}' and '${filter.fieldPath._toPath()}'`,
|
|
254
278
|
);
|
|
255
279
|
}
|
|
256
280
|
}
|
|
257
281
|
}
|
|
258
282
|
|
|
259
|
-
let
|
|
260
|
-
|
|
261
|
-
let hasIn;
|
|
262
|
-
let hasNotIn;
|
|
263
|
-
|
|
264
|
-
for (let i = 0; i < this._filters.length; i++) {
|
|
265
|
-
const filter = this._filters[i];
|
|
283
|
+
for (let i = 0; i < filters.length; i++) {
|
|
284
|
+
const filter = filters[i];
|
|
266
285
|
|
|
267
286
|
if (filter.operator === OPERATORS['array-contains']) {
|
|
268
|
-
if (hasArrayContains) {
|
|
287
|
+
if (this.hasArrayContains) {
|
|
269
288
|
throw new Error('Invalid query. Queries only support a single array-contains filter.');
|
|
270
289
|
}
|
|
271
|
-
hasArrayContains = true;
|
|
290
|
+
this.hasArrayContains = true;
|
|
272
291
|
}
|
|
273
292
|
|
|
274
293
|
if (filter.operator === OPERATORS['array-contains-any']) {
|
|
275
|
-
if (hasArrayContainsAny) {
|
|
294
|
+
if (this.hasArrayContainsAny) {
|
|
276
295
|
throw new Error(
|
|
277
296
|
"Invalid query. You cannot use more than one 'array-contains-any' filter.",
|
|
278
297
|
);
|
|
279
298
|
}
|
|
280
299
|
|
|
281
|
-
if (hasIn) {
|
|
300
|
+
if (this.hasIn) {
|
|
282
301
|
throw new Error(
|
|
283
302
|
"Invalid query. You cannot use 'array-contains-any' filters with 'in' filters.",
|
|
284
303
|
);
|
|
285
304
|
}
|
|
286
305
|
|
|
287
|
-
if (hasNotIn) {
|
|
306
|
+
if (this.hasNotIn) {
|
|
288
307
|
throw new Error(
|
|
289
308
|
"Invalid query. You cannot use 'array-contains-any' filters with 'not-in' filters.",
|
|
290
309
|
);
|
|
291
310
|
}
|
|
292
311
|
|
|
293
|
-
hasArrayContainsAny = true;
|
|
312
|
+
this.hasArrayContainsAny = true;
|
|
294
313
|
}
|
|
295
314
|
|
|
296
315
|
if (filter.operator === OPERATORS.in) {
|
|
297
|
-
if (hasIn) {
|
|
316
|
+
if (this.hasIn) {
|
|
298
317
|
throw new Error("Invalid query. You cannot use more than one 'in' filter.");
|
|
299
318
|
}
|
|
300
319
|
|
|
301
|
-
if (hasArrayContainsAny) {
|
|
320
|
+
if (this.hasArrayContainsAny) {
|
|
302
321
|
throw new Error(
|
|
303
322
|
"Invalid query. You cannot use 'in' filters with 'array-contains-any' filters.",
|
|
304
323
|
);
|
|
305
324
|
}
|
|
306
325
|
|
|
307
|
-
if (hasNotIn) {
|
|
326
|
+
if (this.hasNotIn) {
|
|
308
327
|
throw new Error("Invalid query. You cannot use 'in' filters with 'not-in' filters.");
|
|
309
328
|
}
|
|
310
329
|
|
|
311
|
-
hasIn = true;
|
|
330
|
+
this.hasIn = true;
|
|
312
331
|
}
|
|
313
332
|
|
|
314
333
|
if (filter.operator === OPERATORS['not-in']) {
|
|
315
|
-
if (hasNotIn) {
|
|
334
|
+
if (this.hasNotIn) {
|
|
316
335
|
throw new Error("Invalid query. You cannot use more than one 'not-in' filter.");
|
|
317
336
|
}
|
|
318
337
|
|
|
319
|
-
if (hasNotEqual) {
|
|
338
|
+
if (this.hasNotEqual) {
|
|
320
339
|
throw new Error(
|
|
321
340
|
"Invalid query. You cannot use 'not-in' filters with '!=' inequality filters",
|
|
322
341
|
);
|
|
323
342
|
}
|
|
324
343
|
|
|
325
|
-
if (hasIn) {
|
|
344
|
+
if (this.hasIn) {
|
|
326
345
|
throw new Error("Invalid query. You cannot use 'not-in' filters with 'in' filters.");
|
|
327
346
|
}
|
|
328
347
|
|
|
329
|
-
if (hasArrayContainsAny) {
|
|
348
|
+
if (this.hasArrayContainsAny) {
|
|
330
349
|
throw new Error(
|
|
331
350
|
"Invalid query. You cannot use 'not-in' filters with 'array-contains-any' filters.",
|
|
332
351
|
);
|
|
333
352
|
}
|
|
334
353
|
|
|
335
|
-
hasNotIn = true;
|
|
354
|
+
this.hasNotIn = true;
|
|
336
355
|
}
|
|
337
356
|
}
|
|
338
357
|
}
|
|
@@ -356,6 +375,10 @@ export default class FirestoreQueryModifiers {
|
|
|
356
375
|
}
|
|
357
376
|
|
|
358
377
|
validateOrderBy() {
|
|
378
|
+
this._validateOrderByCheck(this._filters);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
_validateOrderByCheck(filters) {
|
|
359
382
|
// Ensure order hasn't been called on the same field
|
|
360
383
|
if (this._orders.length > 1) {
|
|
361
384
|
const orders = this._orders.map($ => $.fieldPath._toPath());
|
|
@@ -367,13 +390,20 @@ export default class FirestoreQueryModifiers {
|
|
|
367
390
|
}
|
|
368
391
|
|
|
369
392
|
// Skip if no where filters
|
|
370
|
-
if (
|
|
393
|
+
if (filters.length === 0) {
|
|
371
394
|
return;
|
|
372
395
|
}
|
|
373
396
|
|
|
374
397
|
// Ensure the first order field path is equal to the inequality filter field path
|
|
375
|
-
for (let i = 0; i <
|
|
376
|
-
const filter =
|
|
398
|
+
for (let i = 0; i < filters.length; i++) {
|
|
399
|
+
const filter = filters[i];
|
|
400
|
+
|
|
401
|
+
if (filter.queries) {
|
|
402
|
+
// Recursively check sub-queries for Filters
|
|
403
|
+
this._validateOrderByCheck(filter.queries);
|
|
404
|
+
// If it is a Filter query, skip the rest of the loop
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
377
407
|
const filterFieldPath = filter.fieldPath._toPath();
|
|
378
408
|
|
|
379
409
|
for (let k = 0; k < this._orders.length; k++) {
|
package/lib/FirestoreStatics.js
CHANGED
|
@@ -21,13 +21,14 @@ import FirestoreFieldPath from './FirestoreFieldPath';
|
|
|
21
21
|
import FirestoreFieldValue from './FirestoreFieldValue';
|
|
22
22
|
import FirestoreGeoPoint from './FirestoreGeoPoint';
|
|
23
23
|
import FirestoreTimestamp from './FirestoreTimestamp';
|
|
24
|
-
|
|
24
|
+
import { Filter } from './FirestoreFilter';
|
|
25
25
|
export default {
|
|
26
26
|
Blob: FirestoreBlob,
|
|
27
27
|
FieldPath: FirestoreFieldPath,
|
|
28
28
|
FieldValue: FirestoreFieldValue,
|
|
29
29
|
GeoPoint: FirestoreGeoPoint,
|
|
30
30
|
Timestamp: FirestoreTimestamp,
|
|
31
|
+
Filter: Filter,
|
|
31
32
|
|
|
32
33
|
CACHE_SIZE_UNLIMITED: -1,
|
|
33
34
|
|
package/lib/index.d.ts
CHANGED
|
@@ -49,6 +49,47 @@ import { ReactNativeFirebase } from '@react-native-firebase/app';
|
|
|
49
49
|
*/
|
|
50
50
|
export namespace FirebaseFirestoreTypes {
|
|
51
51
|
import FirebaseModule = ReactNativeFirebase.FirebaseModule;
|
|
52
|
+
/**
|
|
53
|
+
* An instance of Filter used to generate Firestore Filter queries.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
export type QueryFilterType = 'OR' | 'AND';
|
|
57
|
+
|
|
58
|
+
export interface QueryFilterConstraint {
|
|
59
|
+
fieldPath: keyof T | FieldPath;
|
|
60
|
+
operator: WhereFilterOp;
|
|
61
|
+
value: any;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface QueryCompositeFilterConstraint {
|
|
65
|
+
operator: QueryFilterType;
|
|
66
|
+
queries: QueryFilterConstraint[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The Filter functions used to generate an instance of Filter.
|
|
70
|
+
*/
|
|
71
|
+
export interface FilterFunction {
|
|
72
|
+
/**
|
|
73
|
+
* The Filter function used to generate an instance of Filter.
|
|
74
|
+
* e.g. Filter('name', '==', 'Ada')
|
|
75
|
+
*/
|
|
76
|
+
(fieldPath: keyof T | FieldPath, operator: WhereFilterOp, value: any): QueryFilterConstraint;
|
|
77
|
+
/**
|
|
78
|
+
* The Filter.or() static function used to generate a logical OR query using multiple Filter instances.
|
|
79
|
+
* e.g. Filter.or(Filter('name', '==', 'Ada'), Filter('name', '==', 'Bob'))
|
|
80
|
+
*/
|
|
81
|
+
or(...queries: QueryFilterConstraint[]): QueryCompositeFilterConstraint;
|
|
82
|
+
/**
|
|
83
|
+
* The Filter.and() static function used to generate a logical AND query using multiple Filter instances.
|
|
84
|
+
* e.g. Filter.and(Filter('name', '==', 'Ada'), Filter('name', '==', 'Bob'))
|
|
85
|
+
*/
|
|
86
|
+
and(...queries: QueryFilterConstraint[]): QueryCompositeFilterConstraint;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The Filter function used to generate an instance of Filter.
|
|
90
|
+
* e.g. Filter('name', '==', 'Ada')
|
|
91
|
+
*/
|
|
92
|
+
export const Filter: FilterFunction;
|
|
52
93
|
|
|
53
94
|
/**
|
|
54
95
|
* An immutable object representing an array of bytes.
|
package/lib/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
module.exports = '17.
|
|
2
|
+
module.exports = '17.5.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-firebase/firestore",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.5.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": "17.
|
|
30
|
+
"@react-native-firebase/app": "17.5.0"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "a58ea4bfd72c903d43844da30d4f3bf5feb0f057"
|
|
36
36
|
}
|