Skip to content

Commit ecea812

Browse files
authored
Merge Realtime RC to main (#1296)
Merges Realtime RC branch to main. RemoteConfig API change: RemoteConfig.AddConfigUpdateListener, takes a listener function as parameter, returns a registration. enables auto-fetching of configs ConfigUpdateRegistration: has a Remove method to remove the listener. Listener function takes a ConfigUpdate and error code as parameters. ConfigUpdate has a set of updated keys. Currently supported on iOS and Android. Desktop implementation is still a stub.
1 parent 65cef69 commit ecea812

22 files changed

+1037
-15
lines changed

Android/firebase_dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def firebaseResourceDependenciesMap = [
5151
'database' : [':database:database_resources'],
5252
'firestore' : [':firestore:firestore_resources'],
5353
'gma' : [':gma:gma_resources'],
54+
'remote_config' : [':remote_config:remote_config_resources'],
5455
'storage' : [':storage:storage_resources']
5556
]
5657

app/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,8 @@ if (IOS)
555555
set(messaging_HDRS
556556
${FIREBASE_SOURCE_DIR}/messaging/src/include/firebase/messaging.h)
557557
set(remote_config_HDRS
558-
${FIREBASE_SOURCE_DIR}/remote_config/src/include/firebase/remote_config.h)
558+
${FIREBASE_SOURCE_DIR}/remote_config/src/include/firebase/remote_config.h
559+
${FIREBASE_SOURCE_DIR}/remote_config/src/include/firebase/remote_config/config_update_listener_registration.h)
559560
set(storage_HDRS
560561
${FIREBASE_SOURCE_DIR}/storage/src/include/firebase/storage.h
561562
${FIREBASE_SOURCE_DIR}/storage/src/include/firebase/storage/common.h

release_build_files/readme.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,12 @@ code.
616616
- Firestore: Added `Query::Count()`, which fetches the number of documents
617617
in the result set without actually downloading the documents
618618
([#1207](https://github.com/firebase/firebase-cpp-sdk/pull/1207)).
619+
- Remote Config: Added support for real-time config updates. Use the new
620+
`addOnConfigUpdateListener` API to get real-time updates. Existing
621+
[`Fetch`](https://firebase.google.com/docs/reference/cpp/class/firebase/remote-config/remote-config#fetch)
622+
and [`Activate`](https://firebase.google.com/docs/reference/cpp/class/firebase/remote-config/remote-config#activate)
623+
APIs aren't affected by this change. To learn more, see
624+
[Get started with Firebase Remote Config](https://firebase.google.com/docs/remote-config/get-started?platform=cpp#add-real-time-listener).
619625

620626
### 10.7.0
621627
- Changes

remote_config/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,23 @@ build_flatbuffers("${flatbuffer_schemas}"
4545
# Common source files used by all platforms
4646
set(common_SRCS
4747
src/common.cc
48+
src/cleanup.h
49+
src/config_update_listener_registration.cc
50+
src/config_update_listener_registration_internal.cc
4851
src/remote_config.cc)
4952

53+
54+
# Run gradle command to make jar
55+
firebase_cpp_gradle(":remote_config:remote_config_resources:generateDexJarRelease"
56+
"${CMAKE_CURRENT_LIST_DIR}/remote_config_resources/build/remote_config_resources_lib.jar")
57+
binary_to_array("remote_config_resources"
58+
"${CMAKE_CURRENT_LIST_DIR}/remote_config_resources/build/remote_config_resources_lib.jar"
59+
"firebase_remote_config"
60+
"${FIREBASE_GEN_FILE_DIR}/remote_config")
61+
5062
# Source files used by the Android implementation.
5163
set(android_SRCS
64+
${remote_config_resources_source}
5265
src/android/remote_config_android.cc)
5366

5467
# Source files used by the iOS implementation.

remote_config/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,5 @@ apply from: "$rootDir/android_build_files/extract_and_dex.gradle"
8484
apply from: "$rootDir/android_build_files/generate_proguard.gradle"
8585
project.afterEvaluate {
8686
generateProguardFile('remote_config')
87+
setupDexDependencies(':remote_config:remote_config_resources')
8788
}

remote_config/integration_test/src/integration_test.cc

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,20 @@
1515
#include <inttypes.h>
1616

1717
#include <algorithm>
18+
#include <chrono>
1819
#include <cstdio>
1920
#include <cstdlib>
2021
#include <cstring>
2122
#include <ctime>
23+
#include <future>
24+
#include <memory>
2225

2326
#include "app_framework.h" // NOLINT
2427
#include "firebase/app.h"
28+
#include "firebase/internal/platform.h"
2529
#include "firebase/log.h"
2630
#include "firebase/remote_config.h"
31+
#include "firebase/remote_config/config_update_listener_registration.h"
2732
#include "firebase/util.h"
2833
#include "firebase_test_framework.h" // NOLINT
2934

@@ -192,6 +197,8 @@ TEST_F(FirebaseRemoteConfigTest, TestInitializeAndTerminate) {
192197
// Already tested via SetUp() and TearDown().
193198
}
194199

200+
/// This test requires to be run on a device or simulator that does not have a
201+
/// newer version of the config saved on disk from a previous test run.
195202
TEST_F(FirebaseRemoteConfigTest, TestSetDefault) {
196203
ASSERT_NE(rc_, nullptr);
197204

@@ -254,6 +261,93 @@ TEST_F(FirebaseRemoteConfigTest, TestSetDefault) {
254261
}
255262
}
256263

264+
/// This test requires to be run on a device or simulator that does not have the
265+
/// template version number stored on the disk or auto-fetch will be skipped.
266+
TEST_F(FirebaseRemoteConfigTest, TestAddOnConfigUpdateListener) {
267+
ASSERT_NE(rc_, nullptr);
268+
269+
// Check if the config has default values. If not, we have cached data
270+
// from a previous test run, and auto-fetch will not happen.
271+
EXPECT_TRUE(WaitForCompletion(SetDefaults(rc_), "SetDefaults"));
272+
bool validated_defaults = true;
273+
firebase::remote_config::ValueInfo value_info;
274+
bool bool_value = rc_->GetBoolean("TestBoolean", &value_info);
275+
bool has_cached_data =
276+
value_info.source != firebase::remote_config::kValueSourceDefaultValue;
277+
278+
if (has_cached_data) {
279+
LogWarning(
280+
"Can't validate defaults, they've been overridden by server values.\n"
281+
#if defined(__ANDROID__)
282+
"Delete the app's data and run this test again to test\n"
283+
" AddOnConfigUpdateListener: adb shell pm clear [bundle ID]"
284+
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
285+
"Uninstall and re-install the app and run this again to test "
286+
"AddOnConfigUpdateListener."
287+
#else // Desktop
288+
"Delete the Remote Config cache and run this test again to test "
289+
"AddOnConfigUpdateListener:\n"
290+
#if defined(_WIN32)
291+
" del remote_config_data"
292+
#else
293+
" rm remote_config_data"
294+
#endif // defined(_WIN32)
295+
#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
296+
);
297+
}
298+
// Realtime RC is not yet supported on desktop.
299+
#if FIREBASE_PLATFORM_DESKTOP
300+
rc_->AddOnConfigUpdateListener(
301+
[](firebase::remote_config::ConfigUpdate&&,
302+
firebase::remote_config::RemoteConfigError) {});
303+
#else
304+
auto config_update_promise = std::make_shared<std::promise<void> >();
305+
306+
firebase::remote_config::ConfigUpdateListenerRegistration registration =
307+
rc_->AddOnConfigUpdateListener(
308+
[&, config_update_promise](
309+
firebase::remote_config::ConfigUpdate&& configUpdate,
310+
firebase::remote_config::RemoteConfigError remoteConfigError) {
311+
EXPECT_EQ(configUpdate.updated_keys.size(), 5);
312+
config_update_promise->set_value();
313+
});
314+
if (!has_cached_data) {
315+
auto config_update_future = config_update_promise->get_future();
316+
ASSERT_EQ(std::future_status::ready,
317+
config_update_future.wait_for(std::chrono::milliseconds(10000)));
318+
319+
// On Android WaitForCompletion must be called from the main thread,
320+
// so Activate is called here outside of the listener.
321+
EXPECT_TRUE(WaitForCompletion(rc_->Activate(), "Activate"));
322+
LogDebug("Real-time Config Update keys retrieved.");
323+
324+
std::map<std::string, firebase::Variant> key_values = rc_->GetAll();
325+
EXPECT_EQ(key_values.size(), 6);
326+
327+
for (auto key_valur_pair : kServerValue) {
328+
firebase::Variant k_value = key_valur_pair.value;
329+
firebase::Variant fetched_value = key_values[key_valur_pair.key];
330+
EXPECT_EQ(k_value.type(), fetched_value.type());
331+
EXPECT_EQ(k_value, fetched_value);
332+
}
333+
registration.Remove();
334+
}
335+
#endif // !FIREBASE_PLATFORM_DESKTOP
336+
}
337+
338+
TEST_F(FirebaseRemoteConfigTest, TestRemoveConfigUpdateListener) {
339+
#if !FIREBASE_PLATFORM_DESKTOP
340+
341+
firebase::remote_config::ConfigUpdateListenerRegistration registration =
342+
rc_->AddOnConfigUpdateListener(
343+
[](firebase::remote_config::ConfigUpdate&& configUpdate,
344+
firebase::remote_config::RemoteConfigError remoteConfigError) {});
345+
346+
registration.Remove();
347+
348+
#endif // !FIREBASE_PLATFORM_DESKTOP
349+
}
350+
257351
TEST_F(FirebaseRemoteConfigTest, TestGetKeys) {
258352
ASSERT_NE(rc_, nullptr);
259353

@@ -405,5 +499,4 @@ TEST_F(FirebaseRemoteConfigTest, TestFetchSecondsParameter) {
405499

406500
FLAKY_TEST_SECTION_END();
407501
}
408-
409502
} // namespace firebase_testapp_automated
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
buildscript {
16+
repositories {
17+
google()
18+
mavenCentral()
19+
}
20+
dependencies {
21+
classpath 'com.android.tools.build:gradle:3.3.3'
22+
classpath 'com.google.gms:google-services:4.2.0'
23+
}
24+
}
25+
allprojects {
26+
repositories {
27+
google()
28+
mavenCentral()
29+
}
30+
}
31+
32+
apply plugin: 'com.android.library'
33+
34+
android {
35+
compileOptions {
36+
sourceCompatibility 1.8
37+
targetCompatibility 1.8
38+
}
39+
compileSdkVersion 28
40+
41+
sourceSets {
42+
main {
43+
manifest.srcFile '../../android_build_files/AndroidManifest.xml'
44+
java {
45+
srcDirs = ['../src_java/com/google/firebase/remoteconfig/internal/cpp']
46+
}
47+
}
48+
}
49+
}
50+
51+
dependencies {
52+
implementation platform('com.google.firebase:firebase-bom:31.5.0')
53+
implementation 'com.google.firebase:firebase-config'
54+
}
55+
56+
afterEvaluate {
57+
generateReleaseBuildConfig.enabled = false
58+
}
59+
60+
apply from: "$rootDir/android_build_files/extract_and_dex.gradle"
61+
extractAndDexAarFile('remote_config_resources')

0 commit comments

Comments
 (0)