From cab0a6ef5fb4cfa9caf80b31caae5a97cddad520 Mon Sep 17 00:00:00 2001 From: Petr Kubes Date: Sat, 23 May 2026 16:30:06 +0200 Subject: [PATCH 1/2] add flutter dependency --- .idea/libraries/Flutter_Plugins.xml | 9 --------- example/pubspec.lock | 24 ++++++++++++------------ ios/facebook_app_events/Package.swift | 2 ++ pubspec.lock | 22 +++++++++++----------- 4 files changed, 25 insertions(+), 32 deletions(-) delete mode 100644 .idea/libraries/Flutter_Plugins.xml diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml deleted file mode 100644 index 53449dae..00000000 --- a/.idea/libraries/Flutter_Plugins.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/example/pubspec.lock b/example/pubspec.lock index 7fd7a576..4f12d9d6 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" clock: dependency: transitive description: @@ -47,7 +47,7 @@ packages: path: ".." relative: true source: path - version: "0.27.1" + version: "0.27.2" fake_async: dependency: transitive description: @@ -94,26 +94,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.19" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" path: dependency: transitive description: @@ -171,10 +171,10 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.11" vector_math: dependency: transitive description: @@ -192,5 +192,5 @@ packages: source: hosted version: "15.0.2" sdks: - dart: ">=3.8.0-0 <4.0.0" + dart: ">=3.10.0-0 <4.0.0" flutter: ">=3.19.0" diff --git a/ios/facebook_app_events/Package.swift b/ios/facebook_app_events/Package.swift index 9ccb496b..de0f0091 100644 --- a/ios/facebook_app_events/Package.swift +++ b/ios/facebook_app_events/Package.swift @@ -18,12 +18,14 @@ let package = Package( .library(name: "facebook-app-events", targets: ["facebook_app_events"]) ], dependencies: [ + .package(name: "FlutterFramework", path: "../FlutterFramework"), .package(url: "https://github.com/facebook/facebook-ios-sdk.git", "18.0.0"..<"19.0.0") ], targets: [ .target( name: "facebook_app_events", dependencies: [ + .product(name: "FlutterFramework", package: "FlutterFramework"), .product(name: "FacebookCore", package: "facebook-ios-sdk"), .product(name: "FacebookBasics", package: "facebook-ios-sdk") ] diff --git a/pubspec.lock b/pubspec.lock index 6aefc9d0..0afcf2d0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" clock: dependency: transitive description: @@ -103,26 +103,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.19" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" path: dependency: transitive description: @@ -180,10 +180,10 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.11" vector_math: dependency: transitive description: @@ -201,5 +201,5 @@ packages: source: hosted version: "14.3.1" sdks: - dart: ">=3.8.0-0 <4.0.0" + dart: ">=3.10.0-0 <4.0.0" flutter: ">=3.19.0" From 4edccf22c90900ef06ee7bf469a831156ec73908 Mon Sep 17 00:00:00 2001 From: Petr Kubes Date: Sat, 23 May 2026 16:41:14 +0200 Subject: [PATCH 2/2] add external id support --- CHANGELOG.md | 1 + README.md | 4 ++++ .../FacebookAppEventsPlugin.kt | 7 +++++++ .../FacebookAppEventsPlugin.swift | 1 + lib/facebook_app_events.dart | 7 +++++++ test/facebook_app_events_test.dart | 21 +++++++++++++++++-- 6 files changed, 39 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfa33b6c..13392993 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 0.27.2 +- Add `externalId` to `setUserData()`. iOS forwards it as `external_id`; Android prints a warning and ignores it until the Facebook Android SDK exposes public support (facebook/facebook-android-sdk#1239). - Tighten the AGP 9 Kotlin-plugin guard introduced in 0.27.1. The previous check skipped `apply plugin: "kotlin-android"` for *any* AGP 9 build, but users running AGP 9 with `android.builtInKotlin=false` (opting out of built-in Kotlin) still need the plugin applied. Now keyed on both the AGP major version and the `android.builtInKotlin` Gradle property (PR [#485](https://github.com/oddbit/flutter_facebook_app_events/pull/485)). - Drop the legacy `kotlinOptions { jvmTarget = "17" }` block in the built-in Kotlin branch. AGP 9 defaults `kotlin.compilerOptions.jvmTarget` to `android.compileOptions.targetCompatibility` (already JVM 17), making it redundant; the legacy DSL is only available when `kotlin-android` is applied, so it's now gated to that branch (PR [#485](https://github.com/oddbit/flutter_facebook_app_events/pull/485)). diff --git a/README.md b/README.md index ffd23b07..1770d022 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,10 @@ Refer to Meta's [Graph API changelog](https://developers.facebook.com/docs/graph This is a plugin-specific workaround for a [known upstream issue in the iOS SDK](https://github.com/facebook/facebook-ios-sdk/issues/2610) and [Android SDK](https://github.com/facebook/facebook-android-sdk/issues/1308). When Meta releases SDK v19.x with a corrected default, this override will become a no-op and the method can safely be removed from your code. +### `setUserData(externalId:)` on Android + +`setUserData(externalId:)` is **functional on iOS** but is currently a **no-op on Android** (a warning is printed). The Facebook Android SDK does not expose public support for passing `external_id` through `AppEventsLogger.setUserData(...)` yet. Track the upstream request at [facebook-android-sdk#1239](https://github.com/facebook/facebook-android-sdk/issues/1239). + ### `setDataProcessingOptions` on iOS `setDataProcessingOptions` is **functional on Android** but is a **no-op on iOS** (a warning is printed). Meta removed the underlying API from the Facebook iOS SDK in the 18.x series; there is no native replacement callable from the SDK. If you need to configure data use on iOS, use Meta's [Data Use Checkup](https://developers.facebook.com/docs/development/data-processing-options) tooling in the app dashboard instead. diff --git a/android/src/main/kotlin/id/oddbit/flutter/facebook_app_events/FacebookAppEventsPlugin.kt b/android/src/main/kotlin/id/oddbit/flutter/facebook_app_events/FacebookAppEventsPlugin.kt index 09ca88ba..1272f5cd 100644 --- a/android/src/main/kotlin/id/oddbit/flutter/facebook_app_events/FacebookAppEventsPlugin.kt +++ b/android/src/main/kotlin/id/oddbit/flutter/facebook_app_events/FacebookAppEventsPlugin.kt @@ -101,6 +101,13 @@ class FacebookAppEventsPlugin: FlutterPlugin, MethodCallHandler { private fun handleSetUserData(call: MethodCall, result: Result) { val parameters = call.arguments as? Map ?: emptyMap() + if (parameters["externalId"] != null) { + Log.w( + logTag, + "setUserData(externalId) is not supported by the Facebook Android SDK yet. " + + "See https://github.com/facebook/facebook-android-sdk/issues/1239." + ) + } val parameterBundle = createBundleFromMap(parameters) AppEventsLogger.setUserData( diff --git a/ios/facebook_app_events/Sources/facebook_app_events/FacebookAppEventsPlugin.swift b/ios/facebook_app_events/Sources/facebook_app_events/FacebookAppEventsPlugin.swift index 27b9753d..d31b1a34 100644 --- a/ios/facebook_app_events/Sources/facebook_app_events/FacebookAppEventsPlugin.swift +++ b/ios/facebook_app_events/Sources/facebook_app_events/FacebookAppEventsPlugin.swift @@ -106,6 +106,7 @@ public class FacebookAppEventsPlugin: NSObject, FlutterPlugin { AppEvents.shared.setUserData(arguments["state"] as? String, forType: FBSDKAppEventUserDataType.state) AppEvents.shared.setUserData(arguments["zip"] as? String, forType: FBSDKAppEventUserDataType.zip) AppEvents.shared.setUserData(arguments["country"] as? String, forType: FBSDKAppEventUserDataType.country) + AppEvents.shared.setUserData(arguments["externalId"] as? String, forType: FBSDKAppEventUserDataType.externalId) result(nil) } diff --git a/lib/facebook_app_events.dart b/lib/facebook_app_events.dart index c02085d0..5c984f58 100644 --- a/lib/facebook_app_events.dart +++ b/lib/facebook_app_events.dart @@ -124,6 +124,12 @@ class FacebookAppEvents { String? state, String? zip, String? country, + + /// iOS-only until the Facebook Android SDK exposes public support. + /// + /// On Android this value is ignored and the native plugin prints a warning + /// referencing https://github.com/facebook/facebook-android-sdk/issues/1239. + String? externalId, }) { final args = { 'email': email, @@ -136,6 +142,7 @@ class FacebookAppEvents { 'state': state, 'zip': zip, 'country': country, + 'externalId': externalId, }; return _channel.invokeMethod('setUserData', _filterOutNulls(args)); diff --git a/test/facebook_app_events_test.dart b/test/facebook_app_events_test.dart index 125351b3..7ca23638 100644 --- a/test/facebook_app_events_test.dart +++ b/test/facebook_app_events_test.dart @@ -118,7 +118,8 @@ void main() { ); }); - test('logCompletedRegistration handles custom parameters and overrides', () async { + test('logCompletedRegistration handles custom parameters and overrides', + () async { await facebookAppEvents.logCompletedRegistration( registrationMethod: 'email', parameters: { @@ -188,7 +189,6 @@ void main() { ), ); }); - }); group('Purchase logging', () { @@ -250,6 +250,22 @@ void main() { ); }); + test('setUserData forwards externalId', () async { + await facebookAppEvents.setUserData( + externalId: 'external-user-123', + ); + + expect( + methodCall, + isMethodCall( + 'setUserData', + arguments: { + 'externalId': 'external-user-123', + }, + ), + ); + }); + test('setUserData sends empty map when all null', () async { await facebookAppEvents.setUserData(); @@ -274,6 +290,7 @@ void main() { state: null, zip: null, country: null, + externalId: null, ); expect(methodCall?.method, 'setUserData');