Migration Steps

Migrate your app from the Marketing Cloud Engagement-specific or Marketing Cloud Next-specific Flutter plugins to the unified Flutter plugin.

Swap Dependencies 

  1. Remove the previous plugin package.
Remove previous plugin packages
1flutter pub remove sfmc
  1. Add the unified product package for each product that you use.
Add unified product packages
1flutter pub add sfmc_marketingcloudsdk
2flutter pub add sfmc_mobileappmessaging
  1. To use the push or in-app messaging feature packages, add them to your configuration.
Add optional feature packages
1flutter pub add sfmc_push
2flutter pub add sfmc_iam
  1. For iOS apps, reinstall your pods.
Reinstall iOS pods
1cd ios
2pod install

Update the Initialization Model 

  1. Replace static SFMCSdk and MobileAppMessaging usage with module initialization through requestSdk().
  2. Initialize required modules at app startup and reuse those instances.
Initialize unified modules
1import 'package:sfmc_core/sfmc_core.dart';
2import 'package:sfmc_marketingcloudsdk/sfmc_marketingcloudsdk.dart';
3import 'package:sfmc_push/sfmc_push.dart';
4import 'package:sfmc_iam/sfmc_iam.dart';
5
6await SFMCSdkModule.requestSdk();
7await MarketingCloudSdk.requestSdk();
8await PushModule.requestSdk();
9await IamModule.requestSdk();

Migrate Dart Call Sites 

  1. Update method calls based on module ownership and method renames.
Previous Flutter Plugin UsageFlutter Unified Plugin UsageModule
setContactKey, getContactKeysetProfileId, getProfileIdSFMCSdkModule
setAttribute, clearAttribute, getAttributes, trackEventsetAttribute, clearAttribute, getAttributes, track (moved)SFMCSdkModule
getSystemTokengetPushTokenPushModule
addTag, removeTag, getTagssame methods (moved)MarketingCloudSdk
getMessages, setMessageRead, deleteMessagegetAllMessages, markMessageRead, markMessageDeletedMarketingCloudSdk
refreshInbox(callback)refreshInbox() (no callback. Returns Future<bool>)MarketingCloudSdk
analytics, piAnalytics, registrationmodule-specific methodsMarketingCloudSdk
MobileAppMessaging.getDeviceId, isAnalyticsEnabled, enableAnalytics, disableAnalyticssame methods (moved)MobileAppMessaging (sfmc_mobileappmessaging)
MobileAppMessaging.registerForRegistrationEvents(callback)setRegistrationCallback() + registrationEvents streamMobileAppMessaging
  1. Find references to previous plugin call sites and update them.
Find previous call sites
1rg "SFMCSdk\\.|MobileAppMessaging\\."
2rg "setContactKey|getContactKey|getSystemToken|setMessageRead|deleteMessage|logSdkState|registerForRegistrationEvents"
  1. Rename essential methods:
  • Change getSystemToken to getPushToken.
  • Change getMessages to getAllMessages.
  • Change setMessageRead to markMessageRead.
  • Change deleteMessage to markMessageDeleted.
  1. Apply these additional required call-site updates:
  • Replace analytics boolean setters with explicit methods:
  • Change setAnalyticsEnabled(true|false) to enableAnalytics() / disableAnalytics().
  • Change setPiAnalyticsEnabled(true|false) to enablePiAnalytics() / disablePiAnalytics().
  • Replace identity APIs:
    • Change setContactKey to setProfileId and change getContactKey to getProfileId on SFMCSdkModule.
  • Update logging and SDK state handling:
    • Change SFMCSdk.enableLogging() and disableLogging() to SFMCSdkModule.setLogging(LogLevel.debug|LogLevel.none).
    • Change logSdkState() to SFMCSdkModule.getSdkState() and log the returned value in your app.
  • Update refreshInbox call sites to drop the callback argument. It now returns Future<bool> directly.
  • Adopt new inbox tracking by using MarketingCloudSdk.trackInboxMessageOpened(id). This method doesn’t have an equivalent in the non-unified plugin.

Migrate the Event Model 

  1. Update CustomEvent calls. The category argument is removed. Use the dedicated event classes instead.
Migrate event tracking
1// Previous Plugin
2// SFMCSdk.trackEvent(CustomEvent('Purchase', attributes: {'Total': 1234}));
3
4// Unified
5await SFMCSdkModule.track(CustomEvent(name: 'Purchase', attributes: {'Total': 1234}));
  1. Validate event attribute value types. Unified event attributes support these value types:
  • String
  • num
  • bool
  1. Convert unsupported payload values from the previous plugin before tracking.

    If payloads from the previous plugin contain nested objects, arrays, or null, convert them to supported value types.

  2. Remove unsupported event patterns from the previous plugin:

  • EventCategory.identity custom events have no direct equivalent in the unified model. Use setProfileId and setAttribute instead.
  • CartEvent, OrderEvent, and CatalogObjectEvent exist in the unified plugin but are deprecated in favor of CustomEvent. If you keep using them, note that their subtype values use short codes, for example, 'comment', instead of the previous plugin’s descriptive factory names (for example, "Comment Catalog Object").

Migrate Event Listeners 

  1. Move callback-based listeners to Stream subscriptions.
Module event subscriptions
1import 'package:sfmc_marketingcloudsdk/sfmc_marketingcloudsdk.dart';
2import 'package:sfmc_mobileappmessaging/sfmc_mobileappmessaging.dart' as mam;
3import 'package:sfmc_push/sfmc_push.dart';
4import 'package:sfmc_iam/sfmc_iam.dart';
5
6// Engagement registration changes:
7final regSub = MarketingCloudSdk.registrationEvents.listen((reg) {
8  print('registration: $reg');
9});
10
11// Marketing Cloud Next registration changes:
12final mamRegSub = mam.MobileAppMessaging.registrationEvents.listen((reg) {
13  print('mam registration: $reg');
14});
15
16// Push token refresh:
17final tokenSub = PushModule.pushTokenStream.listen((token) {
18  print('new token: $token');
19});
20
21// In-App Messaging lifecycle:
22final iamSub = IamModule.inAppMessageEvents.listen((event) {
23  switch (event.type) {
24    case InAppMessageEventType.shouldShow:
25      break;
26    case InAppMessageEventType.didShow:
27      break;
28    case InAppMessageEventType.didClose:
29      break;
30  }
31});
32
33// Always cancel subscriptions when no longer needed:
34regSub.cancel();
35mamRegSub.cancel();
36tokenSub.cancel();
37iamSub.cancel();
  1. Enable the registration callback before subscribing.

    Call setRegistrationCallback() on MarketingCloudSdk or MobileAppMessaging before subscribing to their respective registrationEvents streams.

  2. Apply platform listener caveats:

  • The inbox response listener, registerInboxResponseListener, uses the previous callback-list pattern instead of a Stream.
  • Location-watching APIs (startWatchingLocation, stopWatchingLocation, isWatchingLocation, and getLastKnownLocation) work only with iOS apps.
  • Proximity messaging APIs (enableProximityMessaging, disableProximityMessaging, and isProximityMessagingEnabled) work only with Android apps.
  1. Determine when to display an in-app message.

    Use this capability only if your app needs to allow or suppress in-app messages based on runtime logic.

In-app message decision handler
1IamModule.setInAppMessageDecisionHandler((message) {
2  // Return (or resolve) true to display, false to suppress.
3  return message.title != 'Suppress me';
4});
5
6// Clear the handler (restore default "always show"):
7IamModule.setInAppMessageDecisionHandler(null);

Update Platform-Specific Configurations 

  1. Update both native platforms to the module-based unified configuration model.
  1. Update Android apps to initialize using module-based configuration.
Application.kt
1import com.salesforce.marketingcloud.MarketingCloudConfig
2import com.salesforce.marketingcloud.pushfeature.config.PushFeatureConfig
3import com.salesforce.marketingcloud.inappmessagingfeature.config.InAppMessagingFeatureConfig
4import com.salesforce.marketingcloud.sfmcsdk.SFMCSdk
5import com.salesforce.marketingcloud.sfmcsdk.SFMCSdkModuleConfig
6
7SFMCSdk.configure(this, SFMCSdkModuleConfig.build {
8    engagementModuleConfig = MarketingCloudConfig.builder()
9        .setApplicationId(BuildConfig.MC_APP_ID)
10        .setAccessToken(BuildConfig.MC_ACCESS_TOKEN)
11        .setMarketingCloudServerUrl(BuildConfig.MC_SERVER_URL)
12        .setMid(BuildConfig.MC_MID)
13        .setInboxEnabled(true)
14        .build(this@Application)
15
16    pushFeatureModuleConfig = PushFeatureConfig.builder()
17        .setNotificationCustomizationOptions(/* your notification options */)
18        .setUrlHandler(/* your UrlHandler */)
19        .setShouldShowNotificationListener(/* your ShouldShowNotificationListener */)
20        .build()
21
22    inAppMessagingFeatureModuleConfig = InAppMessagingFeatureConfig.builder()
23        .setUrlHandler(/* your UrlHandler */)
24        .build()
25
26    // If you also migrate Marketing Cloud Next, add its module config
27    // alongside engagementModuleConfig (mamModuleConfig).
28}) { initStatus ->
29    Log.i("SFMC", "SFMC SDK initialization status: $initStatus")
30}
  1. Update iOS apps to initialize using module-based configuration.

    If you also migrate Marketing Cloud Next, add its builder alongside setEngagement.

AppDelegate.swift
1import SFMCSDK
2import PushFeatureSDK
3import InAppMessagingFeatureSDK
4import MarketingCloudSDK
5
6var configBuilder = ConfigBuilder()
7
8if let appEndpoint = URL(string: appEndpointURL) {
9    let engagementConfig = MarketingCloudSdkConfigBuilder(appId: appID)
10        .setAccessToken(accessToken)
11        .setMarketingCloudServerUrl(appEndpoint)
12        .setMid(mid)
13        .setInboxEnabled(true)
14        .setLocationEnabled(true)
15        .setAnalyticsEnabled(true)
16        .build()
17    configBuilder = configBuilder.setEngagement(config: engagementConfig)
18}
19
20let pushConfig = PushFeatureConfigBuilder()
21    .setApplicationControlsBadging(true)
22    .build()
23configBuilder = configBuilder.setPushFeature(config: pushConfig)
24
25let iamConfig = InAppMessagingFeatureConfigBuilder().build()
26configBuilder = configBuilder.setInAppMessagingFeature(config: iamConfig)
27
28SFMCSdk.initializeSdk(configBuilder.build()) { status in
29    // Inspect [ModuleInitStatus] per module.
30}
  1. Verify mandatory platform configuration requirements.
  • Flutter, Dart SDK, iOS, and Android minimums match the unified plugin requirements.

  • Android build minimums match the required versions. For example, minSdk and compileSdk.

  • Android 13+ push permission (POST_NOTIFICATIONS) is requested for push flows.

  • iOS deployment target minimum matches the unified plugin requirement.

  • Keep all existing notification, URL-handling, and delegate forwarding logic when porting to module-based initialization.

    For more information, see Prerequisites.

  1. Find native initialization files and verify your final setup.
Find native initialization files
1rg "SFMCSdk|MarketingCloudConfig|ConfigBuilder" android ios

See Also 

Migration Checklist