Skip to content

Commit f51eeec

Browse files
tom-andersenchkuang-gAlmostMattDellaBittasunmou99
authored
Tomandersen/count api (#1236)
* Firestore COUNT API (#1174) * Firestore COUNT API * Exempt from go/allstar check (#1173) * Token-changed listeners for iOS AppCheck (#1172) * [macOS sandbox mode] Application group name mangling for semaphores (#1167) When macOS Sandbox mode is enabled, macOS requires that semaphores have a name that is prefixed by the App's Group Name. If the semaphore's name doesn't match this convention then its creation fails. Unfortunately there's no official way for the SDK to query the app's group name at runtime, so we can't automatically mangle the semaphore names. Instead I've updated the SDK to use an Info.plist property named FBAppGroupEntitlementName on macOS. If that property is present then the SDK will use it's value to prefix the semaphore names. As an additional issue, the SDK attempted to detect semaphore creation errors by comparing the semaphore handle to nil. But in the case of macOS, a semaphore creation error returns SEM_FAILED which is 0xFFFFFFFFFFFFFFFF, not nil. And on Linux, sem_init returns -1. I've updated the corresponding platform implementations to detect the correct values for these errors. * Setup Desktop test workflow that detects C++ SDK breakage caused by iOS SDK changes (#1162) * [Bugfx] Fix Nightly Test Report template (#1181) * Reduce number of RewardedAd loads on iOS in CI (#1180) The GMA backend doesn't whitelist iOS devices running in CI which means number of ads that can be served to iOS in CI is restricted. This is true even when using the prescribed Demo Ad Unit Id. This PR reduces the number of ads we load on iOS in an attempt to minimize the chance of encountering NoFillErrors and push our CI to green. * Firestore COUNT implementation (WIP) * Firestore COUNT implementation (WIP) * Fix linting * Fix linting * Fix linking * Cleanup * Fix release notes * Format * Fixes from review * Formatting * Responding to PR comments. * Add Hash * Add Hash * Fix copyright year * Rename * Format * Rename * Fixup constructor/assignment parameter naming. * Format --------- Co-authored-by: chkuang-g <[email protected]> Co-authored-by: Matthew Hyndman <[email protected]> Co-authored-by: DellaBitta <[email protected]> Co-authored-by: Mou Sun <[email protected]> * Fix linking * Cleanup * Responding to PR comments. * Rename * Rename * Fixup constructor/assignment parameter naming. * Add Test * Format * Add test * Add test * Format * Recognize NaN filter probelm * Add tests * Add tests * Add tests * Test is_valid() * Add constructor and assignment tests. * Rename variable * Format * Remove extra semicolon * Firestore COUNT API * [macOS sandbox mode] Application group name mangling for semaphores (#1167) When macOS Sandbox mode is enabled, macOS requires that semaphores have a name that is prefixed by the App's Group Name. If the semaphore's name doesn't match this convention then its creation fails. Unfortunately there's no official way for the SDK to query the app's group name at runtime, so we can't automatically mangle the semaphore names. Instead I've updated the SDK to use an Info.plist property named FBAppGroupEntitlementName on macOS. If that property is present then the SDK will use it's value to prefix the semaphore names. As an additional issue, the SDK attempted to detect semaphore creation errors by comparing the semaphore handle to nil. But in the case of macOS, a semaphore creation error returns SEM_FAILED which is 0xFFFFFFFFFFFFFFFF, not nil. And on Linux, sem_init returns -1. I've updated the corresponding platform implementations to detect the correct values for these errors. * Firestore COUNT implementation (WIP) * Firestore COUNT implementation (WIP) * Fix linting * Fix linting * Fix linking * Disable getSessionId test on emulators. (#1193) * Disable getSessionId test on Android emulator. * Also skip on iOS simulator. * Cleanup * Fix release notes * Format * Fixes from review * Formatting * Responding to PR comments. * Add Hash * Add Hash * Fix copyright year * Rename * Format * Rename * Fixup constructor/assignment parameter naming. * Format * Stub Android Impl * Tomandersen/count test (#1206) * Fix linking * Cleanup * Responding to PR comments. * Rename * Rename * Fixup constructor/assignment parameter naming. * Add Test * Format * Add test * Add test * Format * Recognize NaN filter probelm * Add tests * Add tests * Add tests * Test is_valid() * Add constructor and assignment tests. * Rename variable * Format * Remove extra semicolon * Add self move assignment test * Format * Simplify * JNI Count Implementation * Pretty * Fix according PR comments * Pretty --------- Co-authored-by: chkuang-g <[email protected]> Co-authored-by: Matthew Hyndman <[email protected]> Co-authored-by: DellaBitta <[email protected]> Co-authored-by: Mou Sun <[email protected]> Co-authored-by: Jon Simantov <[email protected]>
1 parent 3a66552 commit f51eeec

18 files changed

+465
-14
lines changed

firestore/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ binary_to_array("firestore_resources"
6767

6868
set(android_SRCS
6969
${firestore_resources_source}
70+
src/android/aggregate_query_android.cc
71+
src/android/aggregate_query_android.h
72+
src/android/aggregate_query_snapshot_android.cc
73+
src/android/aggregate_query_snapshot_android.h
74+
src/android/aggregate_source_android.cc
75+
src/android/aggregate_source_android.h
7076
src/android/blob_android.cc
7177
src/android/blob_android.h
7278
src/android/collection_reference_android.cc

firestore/integration_test_internal/src/aggregate_query_snapshot_test.cc

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "firebase/firestore.h"
1817
#include "firestore_integration_test.h"
1918

19+
#include "firebase/firestore.h"
20+
2021
#include "gtest/gtest.h"
2122

2223
#if defined(__ANDROID__)
24+
#include "firestore/src/android/aggregate_query_android.h"
25+
#include "firestore/src/android/aggregate_query_snapshot_android.h"
2326
#include "firestore/src/android/converter_android.h"
27+
#include "firestore/src/jni/object.h"
2428
#else
2529
#include "firestore/src/main/aggregate_query_snapshot_main.h"
2630
#include "firestore/src/main/converter_main.h"
@@ -32,14 +36,27 @@ namespace firestore {
3236
class AggregateQuerySnapshotTest : public FirestoreIntegrationTest {
3337
protected:
3438
static AggregateQuerySnapshot TestAggregateQuerySnapshot(
35-
AggregateQuery aggregate_query, const int count) {
36-
api::AggregateQuery aggregateQuery =
37-
GetInternal(&aggregate_query)->aggregate_query_;
38-
return MakePublic(
39-
AggregateQuerySnapshotInternal(std::move(aggregateQuery), count));
40-
}
39+
AggregateQuery aggregate_query, const int count);
4140
};
4241

42+
#if defined(__ANDROID__)
43+
AggregateQuerySnapshot AggregateQuerySnapshotTest::TestAggregateQuerySnapshot(
44+
firebase::firestore::AggregateQuery aggregate_query, const int count) {
45+
AggregateQueryInternal* internal = GetInternal(&aggregate_query);
46+
FirestoreInternal* firestoreInternal = internal->firestore_internal();
47+
jni::Env env = firestoreInternal->GetEnv();
48+
return AggregateQuerySnapshotInternal::Create(env, *internal, count);
49+
}
50+
#else
51+
AggregateQuerySnapshot AggregateQuerySnapshotTest::TestAggregateQuerySnapshot(
52+
firebase::firestore::AggregateQuery aggregate_query, const int count) {
53+
api::AggregateQuery aggregateQuery =
54+
GetInternal(&aggregate_query)->aggregate_query_;
55+
return MakePublic(
56+
AggregateQuerySnapshotInternal(std::move(aggregateQuery), count));
57+
}
58+
#endif // defined(__ANDROID__)
59+
4360
std::size_t AggregateQuerySnapshotHash(const AggregateQuerySnapshot& snapshot) {
4461
return snapshot.Hash();
4562
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2023 Google LLC
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+
17+
#include "firestore/src/android/aggregate_query_android.h"
18+
19+
#include "firestore/src/android/aggregate_source_android.h"
20+
#include "firestore/src/jni/compare.h"
21+
#include "firestore/src/jni/env.h"
22+
#include "firestore/src/jni/loader.h"
23+
#include "firestore/src/jni/task.h"
24+
25+
namespace firebase {
26+
namespace firestore {
27+
namespace {
28+
29+
using jni::Env;
30+
using jni::Local;
31+
using jni::Method;
32+
using jni::Object;
33+
using jni::Task;
34+
35+
constexpr char kClassName[] =
36+
PROGUARD_KEEP_CLASS "com/google/firebase/firestore/AggregateQuery";
37+
Method<Task> kGet("get",
38+
"(Lcom/google/firebase/firestore/AggregateSource;)"
39+
"Lcom/google/android/gms/tasks/Task;");
40+
Method<Object> kGetQuery("getQuery", "()Lcom/google/firebase/firestore/Query;");
41+
Method<int32_t> kHashCode("hashCode", "()I");
42+
43+
} // namespace
44+
45+
void AggregateQueryInternal::Initialize(jni::Loader& loader) {
46+
loader.LoadClass(kClassName, kGet, kGetQuery, kHashCode);
47+
}
48+
49+
Query AggregateQueryInternal::query() const {
50+
Env env = GetEnv();
51+
Local<Object> query = env.Call(obj_, kGetQuery);
52+
return firestore_->NewQuery(env, query);
53+
}
54+
55+
Future<AggregateQuerySnapshot> AggregateQueryInternal::Get(
56+
AggregateSource aggregate_source) {
57+
Env env = GetEnv();
58+
Local<Object> java_source =
59+
AggregateSourceInternal::Create(env, aggregate_source);
60+
Local<Task> task = env.Call(obj_, kGet, java_source);
61+
return promises_.NewFuture<AggregateQuerySnapshot>(env, AsyncFn::kGet, task);
62+
}
63+
64+
std::size_t AggregateQueryInternal::Hash() const {
65+
Env env = GetEnv();
66+
return env.Call(obj_, kHashCode);
67+
}
68+
69+
bool operator==(const AggregateQueryInternal& lhs,
70+
const AggregateQueryInternal& rhs) {
71+
return jni::EqualityCompareJni(lhs, rhs);
72+
}
73+
74+
} // namespace firestore
75+
} // namespace firebase
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2023 Google LLC
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+
17+
#ifndef FIREBASE_FIRESTORE_SRC_ANDROID_AGGREGATE_QUERY_ANDROID_H_
18+
#define FIREBASE_FIRESTORE_SRC_ANDROID_AGGREGATE_QUERY_ANDROID_H_
19+
20+
#include "firestore/src/android/promise_factory_android.h"
21+
#include "firestore/src/android/query_android.h"
22+
#include "firestore/src/android/wrapper.h"
23+
#include "firestore/src/include/firebase/firestore/aggregate_source.h"
24+
25+
namespace firebase {
26+
namespace firestore {
27+
28+
class AggregateQueryInternal : public Wrapper {
29+
public:
30+
// Each API of AggregateQuery that returns a Future needs to define an enum
31+
// value here. For example, a Future-returning method Foo() relies on the enum
32+
// value kFoo. The enum values are used to identify and manage Future in the
33+
// Firestore Future manager.
34+
enum class AsyncFn {
35+
kGet = 0,
36+
kCount, // Must be the last enum value.
37+
};
38+
39+
static void Initialize(jni::Loader& loader);
40+
41+
AggregateQueryInternal(FirestoreInternal* firestore,
42+
const jni::Object& object)
43+
: Wrapper(firestore, object), promises_(firestore) {}
44+
45+
/**
46+
* @brief Returns the query whose aggregations will be calculated by this
47+
* object.
48+
*/
49+
Query query() const;
50+
51+
/**
52+
* @brief Executes the aggregate query and returns the results as a
53+
* AggregateQuerySnapshot.
54+
*
55+
* @param[in] aggregate_source A value to configure the get behavior.
56+
*
57+
* @return A Future that will be resolved with the results of the
58+
* AggregateQuery.
59+
*/
60+
Future<AggregateQuerySnapshot> Get(AggregateSource aggregate_source);
61+
62+
size_t Hash() const;
63+
64+
private:
65+
PromiseFactory<AsyncFn> promises_;
66+
};
67+
68+
bool operator==(const AggregateQueryInternal& lhs,
69+
const AggregateQueryInternal& rhs);
70+
inline bool operator!=(const AggregateQueryInternal& lhs,
71+
const AggregateQueryInternal& rhs) {
72+
return !(lhs == rhs);
73+
}
74+
75+
} // namespace firestore
76+
} // namespace firebase
77+
78+
#endif // FIREBASE_FIRESTORE_SRC_ANDROID_AGGREGATE_QUERY_ANDROID_H_
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2023 Google LLC
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+
17+
#include "firestore/src/android/aggregate_query_snapshot_android.h"
18+
19+
#include "firestore/src/android/aggregate_query_android.h"
20+
#include "firestore/src/jni/compare.h"
21+
#include "firestore/src/jni/env.h"
22+
#include "firestore/src/jni/loader.h"
23+
24+
namespace firebase {
25+
namespace firestore {
26+
namespace {
27+
28+
using jni::Constructor;
29+
using jni::Env;
30+
using jni::Local;
31+
using jni::Method;
32+
using jni::Object;
33+
34+
constexpr char kClassName[] =
35+
PROGUARD_KEEP_CLASS "com/google/firebase/firestore/AggregateQuerySnapshot";
36+
Constructor<Object> kConstructor(
37+
"(Lcom/google/firebase/firestore/AggregateQuery;J)V");
38+
Method<int64_t> kGetCount("getCount", "()J");
39+
Method<Object> kGetQuery("getQuery",
40+
"()Lcom/google/firebase/firestore/AggregateQuery;");
41+
Method<int32_t> kHashCode("hashCode", "()I");
42+
43+
} // namespace
44+
45+
void AggregateQuerySnapshotInternal::Initialize(jni::Loader& loader) {
46+
loader.LoadClass(kClassName, kConstructor, kGetCount, kGetQuery, kHashCode);
47+
}
48+
49+
AggregateQuerySnapshot AggregateQuerySnapshotInternal::Create(
50+
Env& env, AggregateQueryInternal& aggregate_query_internal, int64_t count) {
51+
const Object& arg = aggregate_query_internal.ToJava();
52+
Local<Object> instance = env.New(kConstructor, arg, count);
53+
return aggregate_query_internal.firestore_internal()
54+
->NewAggregateQuerySnapshot(env, instance);
55+
}
56+
57+
AggregateQuery AggregateQuerySnapshotInternal::query() const {
58+
Env env = GetEnv();
59+
Local<Object> query = env.Call(obj_, kGetQuery);
60+
return firestore_->NewAggregateQuery(env, query);
61+
}
62+
63+
int64_t AggregateQuerySnapshotInternal::count() const {
64+
Env env = GetEnv();
65+
return env.Call(obj_, kGetCount);
66+
}
67+
68+
std::size_t AggregateQuerySnapshotInternal::Hash() const {
69+
Env env = GetEnv();
70+
return env.Call(obj_, kHashCode);
71+
}
72+
73+
bool operator==(const AggregateQuerySnapshotInternal& lhs,
74+
const AggregateQuerySnapshotInternal& rhs) {
75+
return jni::EqualityCompareJni(lhs, rhs);
76+
}
77+
78+
} // namespace firestore
79+
} // namespace firebase
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2023 Google LLC
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+
17+
#ifndef FIREBASE_FIRESTORE_SRC_ANDROID_AGGREGATE_QUERY_SNAPSHOT_ANDROID_H_
18+
#define FIREBASE_FIRESTORE_SRC_ANDROID_AGGREGATE_QUERY_SNAPSHOT_ANDROID_H_
19+
20+
#include "firestore/src/android/wrapper.h"
21+
#include "firestore/src/include/firebase/firestore/aggregate_query.h"
22+
#include "firestore/src/include/firebase/firestore/aggregate_query_snapshot.h"
23+
24+
namespace firebase {
25+
namespace firestore {
26+
27+
class AggregateQuery;
28+
29+
class AggregateQuerySnapshotInternal : public Wrapper {
30+
public:
31+
using Wrapper::Wrapper;
32+
33+
static void Initialize(jni::Loader& loader);
34+
35+
AggregateQuery query() const;
36+
int64_t count() const;
37+
38+
std::size_t Hash() const;
39+
40+
private:
41+
friend class AggregateQuerySnapshotTest;
42+
static AggregateQuerySnapshot Create(
43+
jni::Env& env,
44+
AggregateQueryInternal& aggregate_query_internal,
45+
int64_t count);
46+
};
47+
48+
bool operator==(const AggregateQuerySnapshotInternal& lhs,
49+
const AggregateQuerySnapshotInternal& rhs);
50+
inline bool operator!=(const AggregateQuerySnapshotInternal& lhs,
51+
const AggregateQuerySnapshotInternal& rhs) {
52+
return !(lhs == rhs);
53+
}
54+
55+
} // namespace firestore
56+
} // namespace firebase
57+
58+
#endif // FIREBASE_FIRESTORE_SRC_ANDROID_AGGREGATE_QUERY_SNAPSHOT_ANDROID_H_

0 commit comments

Comments
 (0)