Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package id.oddbit.flutter.facebook_app_events

import androidx.annotation.NonNull

import android.app.Application
import android.os.Bundle
import android.util.Log
import com.facebook.FacebookSdk
Expand All @@ -28,19 +29,25 @@ class FacebookAppEventsPlugin: FlutterPlugin, MethodCallHandler {

private val logTag = "FacebookAppEvents"

private var application: Application? = null

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter.oddbit.id/facebook_app_events")
channel.setMethodCallHandler(this)

application = flutterPluginBinding.applicationContext.applicationContext as? Application
appEventsLogger = AppEventsLogger.newLogger(flutterPluginBinding.applicationContext)
anonymousId = AppEventsLogger.getAnonymousAppDeviceGUID(flutterPluginBinding.applicationContext)
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
application = null
channel.setMethodCallHandler(null)
}

override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"activateApp" -> handleActivateApp(call, result)
"clearUserData" -> handleClearUserData(call, result)
"setUserData" -> handleSetUserData(call, result)
"clearUserID" -> handleClearUserId(call, result)
Expand All @@ -59,6 +66,21 @@ class FacebookAppEventsPlugin: FlutterPlugin, MethodCallHandler {
}
}

private fun handleActivateApp(call: MethodCall, result: Result) {
val application = this.application

if (application == null) {
result.error("missing_application", "could not activate app: Android application is missing", null)
return
}

val applicationId = call.argument("applicationId") as? String

AppEventsLogger.activateApp(application, applicationId)

result.success(null)
}

private fun handleClearUserData(call: MethodCall, result: Result) {
AppEventsLogger.clearUserData()
result.success(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public class FacebookAppEventsPlugin: NSObject, FlutterPlugin {

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "activateApp":
handleActivateApp(call, result: result)
case "clearUserData":
handleClearUserData(call, result: result)
case "setUserData":
Expand Down Expand Up @@ -63,6 +65,17 @@ public class FacebookAppEventsPlugin: NSObject, FlutterPlugin {
}
}

private func handleActivateApp(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let arguments = call.arguments as? [String: Any] ?? [:]

if let applicationId = arguments["applicationId"] as? String, !applicationId.isEmpty {
AppEvents.shared.loggingOverrideAppID = applicationId
}

AppEvents.shared.activateApp()
result(nil)
}

private func handleClearUserData(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
AppEvents.shared.clearUserData()
result(nil)
Expand Down
23 changes: 23 additions & 0 deletions lib/facebook_app_events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,29 @@ class FacebookAppEvents {
/// This could be an EAN, article identifier, etc., depending on the nature of the app.
static const paramNameContentId = "fb_content_id";

/// Notifies the Facebook SDK that the app has launched ("activate app").
///
/// In the default configuration, App Install/App Launch events are logged
/// automatically by the native Facebook SDK.
///
/// Call this method only if you have disabled or delayed automatic app event
/// logging (for example to obtain user consent) and want to log activation
/// manually after enabling/initializing the SDK.
///
/// If `FacebookAutoLogAppEventsEnabled` (iOS) or
/// `com.facebook.sdk.AutoLogAppEventsEnabled` (Android) is set to `false`,
/// call this method to log activation and install events manually.
///
/// Providing an [applicationId] overrides the application ID used by the
/// Facebook SDK on both Android and iOS (with platform-specific behavior).
Future<void> activateApp({String? applicationId}) {
final args = <String, dynamic>{
'applicationId': applicationId,
};

return _channel.invokeMethod<void>('activateApp', _filterOutNulls(args));
}

/// Clears the current user data
Future<void> clearUserData() {
return _channel.invokeMethod<void>('clearUserData');
Expand Down
26 changes: 26 additions & 0 deletions test/facebook_app_events_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,30 @@ void main() {
expect(args!.values.any((v) => v == null), isFalse);
});
});

group('Activation', () {
test('activateApp sends empty args when null', () async {
await facebookAppEvents.activateApp();

expect(
methodCall,
isMethodCall(
'activateApp',
arguments: <String, dynamic>{},
),
);
});

test('activateApp forwards applicationId when provided', () async {
await facebookAppEvents.activateApp(applicationId: '123');

expect(
methodCall,
isMethodCall(
'activateApp',
arguments: <String, dynamic>{'applicationId': '123'},
),
);
});
});
}