Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default params #1707

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
66 changes: 66 additions & 0 deletions analytics/integration_test/src/integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,70 @@ TEST_F(FirebaseAnalyticsTest, TestSetConsent) {
did_test_setconsent_ = true;
}

TEST_F(FirebaseAnalyticsTest, TestSetDefaultEventParameters) {
LogInfo("Testing SetDefaultEventParameters().");

// Set some default parameters with various types.
std::map<std::string, firebase::Variant> defaults;
defaults["default_int"] = static_cast<int64_t>(123); // int64_t
defaults["default_double"] = 45.67; // double
defaults["default_bool"] = true; // bool
defaults["default_string"] = "test_string_value"; // const char*
defaults["default_to_clear"] = "will_be_cleared"; // Another string

firebase::analytics::SetDefaultEventParameters(defaults);
LogInfo("Set initial default parameters.");

// Log an event - the defaults should be included automatically by the
// underlying SDK if logging immediately after setting is supported.
// Verification might need manual checking in the Analytics console or
// via platform-specific debug logs if possible.
firebase::analytics::LogEvent("event_with_mixed_defaults");
LogInfo("Logged event_with_mixed_defaults");

// Clear one default parameter and update another.
defaults["default_to_clear"] = firebase::Variant::Null(); // Clear this one
defaults["default_int"] = static_cast<int64_t>(999); // Update this one
firebase::analytics::SetDefaultEventParameters(defaults);
LogInfo("Cleared one parameter and updated another.");

// Log another event.
firebase::analytics::LogEvent("event_with_one_default_cleared");
LogInfo("Logged event_with_one_default_cleared");

// Set only one parameter, clearing others implicitly if underlying SDK works
// like that
std::map<std::string, firebase::Variant> single_default;
single_default["only_this_double"] = 78.9;
firebase::analytics::SetDefaultEventParameters(single_default);
LogInfo("Set a single different default parameter.");
firebase::analytics::LogEvent(
"event_with_only_one_default"); // Changed log event name slightly
LogInfo("Logged event_with_only_one_default");

// If we reach here without crashing, consider the basic test passed for the
// C++ layer. Deeper verification requires platform tools.
LogInfo("SetDefaultEventParameters() tests completed.");
}

TEST_F(FirebaseAnalyticsTest, TestClearDefaultEventParameters) {
LogInfo("Testing ClearDefaultEventParameters().");

// Set some defaults first.
std::map<std::string, firebase::Variant> defaults;
defaults["temp_default"] = "will_be_cleared";
firebase::analytics::SetDefaultEventParameters(defaults);

// Now clear them all.
firebase::analytics::ClearDefaultEventParameters();

// Log an event - no defaults should be included.
firebase::analytics::LogEvent("event_after_clear_defaults");
LogInfo("Logged event_after_clear_defaults");

// If we reach here without crashing, consider the basic test passed for the
// C++ layer.
LogInfo("ClearDefaultEventParameters() test completed.");
}

} // namespace firebase_testapp_automated
60 changes: 60 additions & 0 deletions analytics/src/analytics_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ static const ::firebase::App* g_app = nullptr;
"()Lcom/google/android/gms/tasks/Task;"), \
X(GetSessionId, "getSessionId", \
"()Lcom/google/android/gms/tasks/Task;"), \
X(SetDefaultEventParameters, "setDefaultEventParameters", \
"(Landroid/os/Bundle;)V"), \
X(GetInstance, "getInstance", "(Landroid/content/Context;)" \
"Lcom/google/firebase/analytics/FirebaseAnalytics;", \
firebase::util::kMethodTypeStatic)
Expand Down Expand Up @@ -518,6 +520,64 @@ void LogEvent(const char* name, const Parameter* parameters,
});
}

// Convert std::map<std::string, Variant> to Bundle.
jobject StringVariantMapToBundle(JNIEnv* env,
const std::map<std::string, Variant>& map) {
jobject bundle =
env->NewObject(util::bundle::GetClass(),
util::bundle::GetMethodId(util::bundle::kConstructor));
for (const auto& pair : map) {
// Bundle keys must be strings.
const char* key = pair.first.c_str();
const Variant& value = pair.second;
// A null variant clears the default parameter for that key.
// The Android SDK uses Bundle.putString(key, null) for this.
if (value.is_null()) {
jstring key_string = env->NewStringUTF(key);
// Call Bundle.putString(key, null)
env->CallVoidMethod(bundle,
util::bundle::GetMethodId(util::bundle::kPutString),
key_string, nullptr);
util::CheckAndClearJniExceptions(env);
env->DeleteLocalRef(key_string);
} else if (!AddVariantToBundle(env, bundle, key, value)) {
LogError("SetDefaultEventParameters: Unsupported type (%s) for key %s.",
Variant::TypeName(value.type()), key);
}
// CheckAndClearJniExceptions is called within AddVariantToBundle or above
// for the null case.
}
return bundle;
}

void SetDefaultEventParameters(
const std::map<std::string, Variant>& default_parameters) {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
JNIEnv* env = g_app->GetJNIEnv();

jobject bundle = StringVariantMapToBundle(env, default_parameters);

env->CallVoidMethod(
g_analytics_class_instance,
analytics::GetMethodId(analytics::kSetDefaultEventParameters), bundle);

util::CheckAndClearJniExceptions(env);
env->DeleteLocalRef(bundle);
}

void ClearDefaultEventParameters() {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
JNIEnv* env = g_app->GetJNIEnv();

// Call FirebaseAnalytics.setDefaultEventParameters(null)
env->CallVoidMethod(
g_analytics_class_instance,
analytics::GetMethodId(analytics::kSetDefaultEventParameters),
nullptr); // Pass null Bundle to clear all parameters

util::CheckAndClearJniExceptions(env);
}

/// Initiates on-device conversion measurement given a user email address on iOS
/// (no-op on Android). On iOS, requires dependency
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
Expand Down
31 changes: 31 additions & 0 deletions analytics/src/analytics_ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,37 @@ void LogEvent(const char* name, const Parameter* parameters, size_t number_of_pa
[FIRAnalytics logEventWithName:@(name) parameters:parameters_dict];
}

void SetDefaultEventParameters(const std::map<std::string, Variant>& default_parameters) {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
// Convert the std::map<std::string, Variant> to NSDictionary*
// The keys must be strings for FIRAnalytics.
NSMutableDictionary* parameters_dict =
[NSMutableDictionary dictionaryWithCapacity:default_parameters.size()];
for (const auto& pair : default_parameters) {
NSString* key = firebase::util::StringToNSString(pair.first);
// A null Variant indicates the default parameter for that key should be
// cleared. In ObjC, setting a key to [NSNull null] in the dictionary
// achieves this.
id value = pair.second.is_null() ? [NSNull null] : firebase::util::VariantToId(pair.second);
if (value) {
[parameters_dict setObject:value forKey:key];
} else {
// VariantToId could return nil if the variant type is unsupported.
// Log an error but continue, as NSNull case is handled above.
LogError("SetDefaultEventParameters: Failed to convert value for key %s.",
pair.first.c_str());
}
}

[FIRAnalytics setDefaultEventParameters:parameters_dict];
}

void ClearDefaultEventParameters() {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
// Passing nil to the underlying SDK method clears all parameters.
[FIRAnalytics setDefaultEventParameters:nil];
}

/// Initiates on-device conversion measurement given a user email address on iOS (no-op on
/// Android). On iOS, requires dependency GoogleAppMeasurementOnDeviceConversion to be linked
/// in, otherwise it is a no-op.
Expand Down
11 changes: 11 additions & 0 deletions analytics/src/analytics_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ void LogEvent(const char* /*name*/, const Parameter* /*parameters*/,
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
}

void SetDefaultEventParameters(
const std::map<std::string, Variant>& default_parameters) {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
// No-op on stub.
}

void ClearDefaultEventParameters() {
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
// No-op on stub.
}

/// Initiates on-device conversion measurement given a user email address on iOS
/// (no-op on Android). On iOS, requires dependency
/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a
Expand Down
15 changes: 15 additions & 0 deletions analytics/src/include/firebase/analytics.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,21 @@ void LogEvent(const char* name);
void LogEvent(const char* name, const Parameter* parameters,
size_t number_of_parameters);

/// @brief Sets default event parameters for this app.
///
/// This specifies parameters to be included with every subsequent call to
/// `LogEvent`, in addition to the parameters passed to `LogEvent`.
/// The same limitations apply to these parameters as are documented for
/// `LogEvent`.
/// @param[in] default_parameters Map of default parameter names and values.
/// Passing a null `Variant` value for a parameter name clears the default
/// parameter for that key.
void SetDefaultEventParameters(
const std::map<std::string, Variant>& default_parameters);

/// @brief Clears all default event parameters.
void ClearDefaultEventParameters();

/// Initiates on-device conversion measurement given a user email address on iOS
/// and tvOS (no-op on Android). On iOS and tvOS, this method requires the
/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in,
Expand Down
5 changes: 5 additions & 0 deletions release_build_files/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,11 @@ workflow use only during the development of your app, not for publicly shipping
code.

## Release Notes
### Upcoming Release
- Changes
- Analytics: Add SetDefaultEventParams to set default parameters for
all LogEvent calls.

### 12.7.0
- Changes
- General (iOS): Update to Firebase Cocoapods version 11.10.0.
Expand Down
Loading