diff --git a/analytics/integration_test/src/integration_test.cc b/analytics/integration_test/src/integration_test.cc index bedccee516..7b398cf43e 100644 --- a/analytics/integration_test/src/integration_test.cc +++ b/analytics/integration_test/src/integration_test.cc @@ -341,4 +341,15 @@ TEST_F(FirebaseAnalyticsTest, TestSetConsent) { did_test_setconsent_ = true; } +TEST_F(FirebaseAnalyticsTest, TestSetDefaultEventParameters) { + std::map default_params = { + {"key1", firebase::Variant("value1")}, + {"key2", firebase::Variant(12345)}, + {"key3", firebase::Variant(1.01)}, + {"key4", firebase::Variant("my_value")}, + {"key5", firebase::Variant(true)}, + {"key6", firebase::Variant::EmptyMap()}, + }; + firebase::analytics::SetDefaultEventParameters(default_params); +} } // namespace firebase_testapp_automated diff --git a/analytics/src/analytics_android.cc b/analytics/src/analytics_android.cc index d1279c6ba7..af4610dd77 100644 --- a/analytics/src/analytics_android.cc +++ b/analytics/src/analytics_android.cc @@ -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) @@ -736,5 +738,59 @@ Future GetSessionIdLastResult() { internal::kAnalyticsFnGetSessionId)); } +// Sets the default parameters to be sent with each event. +void SetDefaultEventParameters( + const std::map& parameters) { + FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized()); + JNIEnv* env = g_app->GetJNIEnv(); + + jobject map = + env->NewObject(util::hash_map::GetClass(), + util::hash_map::GetMethodId(util::hash_map::kConstructor)); + util::CheckAndClearJniExceptions(env); + + jmethodID put_method_id = util::map::GetMethodId(util::map::kPut); + + for (const auto& pair : parameters) { + jobject jni_value; + if (pair.second.is_int64()) { + jni_value = env->NewObject( + util::integer_class::GetClass(), + util::integer_class::GetMethodId(util::integer_class::kConstructor), + pair.second.int64_value()); + } else if (pair.second.is_double()) { + jni_value = env->NewObject( + util::double_class::GetClass(), + util::double_class::GetMethodId(util::double_class::kConstructor), + pair.second.double_value()); + } else if (pair.second.is_string()) { + jni_value = env->NewStringUTF(pair.second.string_value()); + } else if (pair.second.is_map()) { + jni_value = MapToBundle(env, pair.second.map()); + } else { + // A Variant type that couldn't be handled was passed in. + LogError( + "LogEvent(%s): %s is not a valid parameter value type. " + "No event was logged.", + pair.first.c_str(), Variant::TypeName(pair.second.type())); + continue; + } + jstring key_string = env->NewStringUTF(pair.first.c_str()); + jobject previous_value = + env->CallObjectMethod(map, put_method_id, key_string, jni_value); + util::CheckAndClearJniExceptions(env); + env->DeleteLocalRef(jni_value); + env->DeleteLocalRef(key_string); + env->DeleteLocalRef(previous_value); + } + + env->CallVoidMethod( + g_analytics_class_instance, + analytics::GetMethodId(analytics::kSetDefaultEventParameters), map); + + util::CheckAndClearJniExceptions(env); + env->DeleteLocalRef(map); +} + } // namespace analytics } // namespace firebase diff --git a/analytics/src/analytics_ios.mm b/analytics/src/analytics_ios.mm index d56fd61356..922ebbaa15 100644 --- a/analytics/src/analytics_ios.mm +++ b/analytics/src/analytics_ios.mm @@ -438,5 +438,22 @@ Thread get_id_thread( internal::FutureData::Get()->api()->LastResult(internal::kAnalyticsFnGetSessionId)); } +/// @brief Sets the default parameters to be sent with each event. +/// +/// @param[in] parameters The parameters to send with each event. +void SetDefaultEventParameters(const std::map& parameters) { + FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized()); + NSMutableDictionary* parameters_dict = + [[NSMutableDictionary alloc] initWithCapacity:parameters.size()]; + for (const auto& pair : parameters) { + NSString* key = SafeString(pair.first.c_str()); + if (!AddVariantToDictionary(parameters_dict, key, pair.second)) { + LogError("SetDefaultEventParameters: Unsupported type (%s) within map with key %s.", + Variant::TypeName(pair.second.type()), key); + } + } + [FIRAnalytics setDefaultEventParameters:parameters_dict]; +} + } // namespace analytics } // namespace firebase diff --git a/analytics/src/analytics_stub.cc b/analytics/src/analytics_stub.cc index 37c4b3520b..3f51ffbdab 100644 --- a/analytics/src/analytics_stub.cc +++ b/analytics/src/analytics_stub.cc @@ -186,5 +186,11 @@ Future GetSessionIdLastResult() { internal::kAnalyticsFnGetSessionId)); } +// Sets the default parameters to be sent with each event. +void SetDefaultEventParameters( + const std::map& parameters) { + FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized()); +} + } // namespace analytics } // namespace firebase diff --git a/analytics/src/include/firebase/analytics.h b/analytics/src/include/firebase/analytics.h index 746df99894..6efc60048c 100644 --- a/analytics/src/include/firebase/analytics.h +++ b/analytics/src/include/firebase/analytics.h @@ -591,6 +591,12 @@ Future GetSessionId(); /// app session. Future GetSessionIdLastResult(); +/// @brief Sets the default parameters to be sent with each event. +/// +/// @param[in] parameters The parameters to send with each event. +void SetDefaultEventParameters( + const std::map& parameters); + } // namespace analytics } // namespace firebase diff --git a/analytics/tests/analytics_test.cc b/analytics/tests/analytics_test.cc index 8235c69e25..2d80b4c8f6 100644 --- a/analytics/tests/analytics_test.cc +++ b/analytics/tests/analytics_test.cc @@ -296,5 +296,25 @@ TEST_F(AnalyticsTest, TestGetAnalyticsInstanceId) { EXPECT_EQ(std::string("FakeAnalyticsInstanceId0"), *result.result()); } +TEST_F(AnalyticsTest, TestSetDefaultEventParameters) { + std::map parameters = { + {"key1", firebase::Variant("value1")}, + {"key2", firebase::Variant(12345)}, + {"key3", firebase::Variant(1.01)}, + {"key4", firebase::Variant("my_value")}, + {"key5", firebase::Variant(true)}, + {"key6", firebase::Variant::EmptyMap()}, + }; + + AddExpectationAndroid( + "FirebaseAnalytics.setDefaultEventParameters", + {"key1=value1,key2=12345,key3=1.01,key4=my_value,key5=1"}); + AddExpectationApple( + "+[FIRAnalytics setDefaultEventParameters:]", + {"key1=value1,key2=12345,key3=1.01,key4=my_value,key5=1"}); + + SetDefaultEventParameters(parameters); +} + } // namespace analytics } // namespace firebase diff --git a/release_build_files/readme.md b/release_build_files/readme.md index c659c7f452..6f026792af 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -631,6 +631,13 @@ workflow use only during the development of your app, not for publicly shipping code. ## Release Notes +### 12.7.0 +- Changes + - General (iOS): Update to Firebase Cocoapods version 11.9.0. + - General (Android): Update to Firebase Android BoM version 33.10.0. + - Analytics: Added support for setting default parameters to be sent + with each event, using `SetDefaultEventParameters`. + ### 12.6.0 - Changes - General (iOS): Update to Firebase Cocoapods version 11.8.1.