Skip to content

Commit edcea54

Browse files
authored
fix: remove null value inclusion from whereNotEqualTo and whereNotIn filter results (#6859)
1 parent cad26b9 commit edcea54

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

firebase-firestore/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Unreleased
2-
2+
* [fixed] Fixed the `null` value handling in `whereNotEqualTo` and `whereNotIn` filters.
33

44
# 25.1.3
55
* [fixed] Use lazy encoding in UTF-8 encoded byte comparison for strings to solve performance issues. [#6706](//github.com/firebase/firebase-android-sdk/pull/6706)

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/QueryTest.java

+49
Original file line numberDiff line numberDiff line change
@@ -1647,4 +1647,53 @@ public void testOrderByEquality() {
16471647
Query query2 = collection.where(inArray("a", asList(2, 3))).orderBy("a");
16481648
checkOnlineAndOfflineResultsMatch(collection, query2, "doc6", "doc3");
16491649
}
1650+
1651+
@Test
1652+
public void testSDKUsesNotEqualFiltersSameAsServer() {
1653+
Map<String, Map<String, Object>> testDocs =
1654+
map(
1655+
"a", map("zip", Double.NaN),
1656+
"b", map("zip", 91102L),
1657+
"c", map("zip", 98101L),
1658+
"d", map("zip", "98101"),
1659+
"e", map("zip", asList(98101L)),
1660+
"f", map("zip", asList(98101L, 98102L)),
1661+
"g", map("zip", asList("98101", map("zip", 98101L))),
1662+
"h", map("zip", map("code", 500L)),
1663+
"i", map("zip", null),
1664+
"j", map("code", 500L));
1665+
CollectionReference collection = testCollectionWithDocs(testDocs);
1666+
1667+
Query query = collection.whereNotEqualTo("zip", 98101L);
1668+
checkOnlineAndOfflineResultsMatch(collection, query, "a", "b", "d", "e", "f", "g", "h");
1669+
1670+
query = collection.whereNotEqualTo("zip", Double.NaN);
1671+
checkOnlineAndOfflineResultsMatch(collection, query, "b", "c", "d", "e", "f", "g", "h");
1672+
1673+
query = collection.whereNotEqualTo("zip", null);
1674+
checkOnlineAndOfflineResultsMatch(collection, query, "a", "b", "c", "d", "e", "f", "g", "h");
1675+
}
1676+
1677+
@Test
1678+
public void testSDKUsesNotInFiltersSameAsServer() {
1679+
Map<String, Map<String, Object>> testDocs =
1680+
map(
1681+
"a", map("zip", Double.NaN),
1682+
"b", map("zip", 91102L),
1683+
"c", map("zip", 98101L),
1684+
"d", map("zip", "98101"),
1685+
"e", map("zip", asList(98101L)),
1686+
"f", map("zip", asList(98101L, 98102L)),
1687+
"g", map("zip", asList("98101", map("zip", 98101L))),
1688+
"h", map("zip", map("code", 500L)),
1689+
"i", map("zip", null),
1690+
"j", map("code", 500L));
1691+
CollectionReference collection = testCollectionWithDocs(testDocs);
1692+
1693+
Query query = collection.whereNotIn("zip", asList(98101L, 98103L, asList(98101L, 98102L)));
1694+
checkOnlineAndOfflineResultsMatch(collection, query, "a", "b", "d", "e", "g", "h");
1695+
1696+
query = collection.whereNotIn("zip", nullList());
1697+
checkOnlineAndOfflineResultsMatch(collection, query);
1698+
}
16501699
}

firebase-firestore/src/main/java/com/google/firebase/firestore/core/FieldFilter.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ public boolean matches(Document doc) {
115115
Value other = doc.getField(field);
116116
// Types do not have to match in NOT_EQUAL filters.
117117
if (operator == Operator.NOT_EQUAL) {
118-
return other != null && this.matchesComparison(Values.compare(other, value));
118+
return other != null
119+
&& !other.hasNullValue()
120+
&& this.matchesComparison(Values.compare(other, value));
119121
}
120122
// Only compare types with matching backend order (such as double and int).
121123
return other != null

firebase-firestore/src/main/java/com/google/firebase/firestore/core/NotInFilter.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public boolean matches(Document doc) {
3434
return false;
3535
}
3636
Value other = doc.getField(getField());
37-
return other != null && !Values.contains(getValue().getArrayValue(), other);
37+
return other != null
38+
&& !other.hasNullValue()
39+
&& !Values.contains(getValue().getArrayValue(), other);
3840
}
3941
}

firebase-firestore/src/test/java/com/google/firebase/firestore/core/QueryTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ public void testNotInFilters() {
237237

238238
// Null match.
239239
document = doc("collection/1", 0, map("zip", null));
240-
assertTrue(query.matches(document));
240+
assertFalse(query.matches(document));
241241

242242
// NaN match.
243243
document = doc("collection/1", 0, map("zip", Double.NaN));
@@ -333,7 +333,7 @@ public void testNaNFilter() {
333333
assertTrue(query.matches(doc3));
334334
assertTrue(query.matches(doc4));
335335
assertTrue(query.matches(doc5));
336-
assertTrue(query.matches(doc6));
336+
assertFalse(query.matches(doc6));
337337
}
338338

339339
@Test

0 commit comments

Comments
 (0)