Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ Release Notes
- Changes
- Messaging: Added new Registration methods using Installation Ids.
Deprecated old Token based methods.
- Remote Config: Add support for setting Custom Signals.

### 13.15.0
- Changes
Expand Down
30 changes: 30 additions & 0 deletions remote_config/src/FirebaseRemoteConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,36 @@ public Task SetDefaultsAsync(IDictionary<string, object> defaults) {
RemoteConfigUtil.ConvertDictionaryToMap(defaults));
}

/// @brief Sets the custom signals values based on the input dictionary.
///
/// @note This upserts the custom signals, i.e., inserts a new signal if none exists
/// or updates the signal if it does.
///
/// @param customSignals IDictionary of string keys to object values, representing the
/// set of custom signals to apply. Supported value types are string, long (and integer types),
/// double (and float types), or null to remove a signal.
/// If the same key is specified multiple times, the value associated with the last
/// duplicate key is applied.
///
/// @return A Task which can be used to determine when the operation is
/// complete.
public Task SetCustomSignalsAsync(IDictionary<string, object> customSignals) {
ThrowIfNull();
if (customSignals == null) {
throw new System.ArgumentNullException(nameof(customSignals));
}
using StringList signalKeys = new StringList();
using VariantList signalValues = new VariantList();
foreach (KeyValuePair<string, object> pair in customSignals) {
if (pair.Key == null) {
throw new System.ArgumentException("Key cannot be null", nameof(customSignals));
}
signalKeys.Add(pair.Key);
signalValues.Add(Variant.FromObject(pair.Value));
}
return remoteConfigInternal.SetCustomSignalsInternalAsync(signalKeys, signalValues);
}
Comment thread
a-maurice marked this conversation as resolved.

/// @brief Asynchronously changes the settings for this Remote Config
/// instance.
///
Expand Down
18 changes: 18 additions & 0 deletions remote_config/src/swig/remote_config.i
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <vector>
#include "app/src/callback.h"
#include "app/src/cpp_instance_manager.h"
#include "app/src/log.h"
#include "remote_config/src/include/firebase/remote_config.h"

namespace firebase {
Expand Down Expand Up @@ -135,6 +136,7 @@ void SetConfigUpdateCallback(RemoteConfig* rc, firebase::remote_config::ConfigUp
%ignore firebase::remote_config::RemoteConfig::GetInstance;

%ignore firebase::remote_config::RemoteConfig::SetDefaults;
%ignore firebase::remote_config::RemoteConfig::SetCustomSignals;
// Ignore the various Get<Types>, as GetValue is used instead.
%ignore firebase::remote_config::RemoteConfig::GetBoolean;
%ignore firebase::remote_config::RemoteConfig::GetLong;
Expand Down Expand Up @@ -280,6 +282,22 @@ void SetConfigUpdateCallback(firebase::remote_config::RemoteConfig* rc,
delete[] default_array;
return future_result;
}

Future<void> SetCustomSignalsInternal(
std::vector<std::string> keys,
std::vector<firebase::Variant> values) {
if (keys.size() != values.size()) {
firebase::LogError(
"SetCustomSignalsInternal given different list sizes (%zu, %zu)",
keys.size(), values.size());
return firebase::Future<void>();
}
std::map<std::string, firebase::Variant> custom_signals;
for (size_t i = 0; i < keys.size(); ++i) {
custom_signals[keys[i]] = values[i];
}
return self->SetCustomSignals(custom_signals);
}
}

// 314: Ignore warnings about the internal namespace being renamed to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,23 @@ void FetchComplete(Task fetchTask) {
}
}


public Task SetCustomSignalsAsync() {
DebugLog("Setting custom signals...");
var customSignals = new System.Collections.Generic.Dictionary<string, object> {
{ "item_id", "sword_123" },
{ "player_level", 42 },
{ "item_rating", 4.5 }
};
return Firebase.RemoteConfig.FirebaseRemoteConfig.DefaultInstance
.SetCustomSignalsAsync(customSignals)
.ContinueWithOnMainThread(task => {
if (task.IsFaulted) {
DebugLog("Failed to set custom signals: " + task.Exception);
} else {
DebugLog("Custom signals set successfully!");
}
});
}

// Output text to the debug log text field, as well as the console.
public void DebugLog(string s) {
Expand Down Expand Up @@ -234,6 +250,9 @@ void GUIDisplayControls() {
if (GUILayout.Button("Display All Keys")) {
DisplayAllKeys();
}
if (GUILayout.Button("Set Custom Signals")) {
SetCustomSignalsAsync();
}
if (GUILayout.Button("Fetch Remote Data")) {
FetchDataAsync();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ protected override void Start() {
TestAddAndRemoveConfigUpdateListener,
#endif // !(UNITY_IOS || UNITY_TVOS || UNITY_ANDROID) || UNITY_EDITOR
TestFetchData,
TestSetCustomSignals,
};
testRunner = AutomatedTestRunner.CreateTestRunner(
testsToRun: tests,
Expand Down Expand Up @@ -160,5 +161,30 @@ Task TestFetchData() {
FirebaseRemoteConfig.DefaultInstance.GetValue("config_test_bool").BooleanValue);
});
}

async Task TestSetCustomSignals() {
var signals = new System.Collections.Generic.Dictionary<string, object> {
{ "test_string", "alpha" },
{ "test_int", 42 },
{ "test_double", 3.14 }
};
await FirebaseRemoteConfig.DefaultInstance.SetCustomSignalsAsync(signals);

// After setting the Custom Signal, fetch to get the signal data
await FirebaseRemoteConfig.DefaultInstance.FetchAsync(TimeSpan.Zero);
await FirebaseRemoteConfig.DefaultInstance.ActivateAsync();

// Because of caching, this isn't the most reliable test, so just print out the value.
DebugLog("Check custom value: " +
FirebaseRemoteConfig.DefaultInstance.GetValue("config_test_with_custom_signal").StringValue);

// Set the custom signals back to null, to clear them out.
var signals2 = new System.Collections.Generic.Dictionary<string, object> {
{ "test_string", null },
{ "test_int", null },
{ "test_double", null }
};
await FirebaseRemoteConfig.DefaultInstance.SetCustomSignalsAsync(signals2);
}
Comment thread
a-maurice marked this conversation as resolved.
}
}