Flutter SDK 3.x to 4.0 migration guide
Read time: 7 minutes
Last edited: Jun 14, 2024
Overview
This topic explains the changes in the Flutter SDK version 4 release and how to migrate to that version.
Version 4.0 includes breaking changes. Version 4 of the Flutter SDK is now implemented in Flutter and supports development on all Flutter platforms.
As part of this update, version 4 includes the following changes:
- The Flutter SDK now uses either a mobile key or a client-side ID as its credential, depending on the platform that you build for. To learn more, read Understanding changes to initialization.
- Setting the configuration options no longer uses a builder pattern. You can set the configuration options directly, including the credential. Then, pass the configuration object to the client when you instantiate it. To learn more, read Understanding changes to LDConfig.
- The
LDClient
is not required to be a singleton. Instead, you instantiate the client with configuration options and a context, and then call functions on this instance. To learn more, read Understanding changes to LDClient and LDValue. - Most of the
LDClient
methods are now synchronous, and do not needawait
. To learn more, read Understanding changes to LDClient and LDValue. - The mechanics of some of the connecting, listening, and fetching functionality has changed. To learn more, read Understanding changes to connecting, listening, and fetching.
- Anonymous contexts now have the same behavior across all platforms. Anonymous contexts now respect the key provided. In the Flutter SDK version 3, anonymous contexts on Android would have their provided key overwritten with a generated key, while anonymous contexts on iOS would have their provided key respected.
- The
LDContext
builder now provides setters for primitive types, so that you do not need to create theLDValue
s yourself. Each setter also provides an optional parameter to indicate whether the attribute is private. To learn more, read Understanding changes to LDContext. - Logging is now available. To learn more, read Logging.
Additionally, when you migrate from the existing Flutter SDK version 3 to the new Flutter SDK version 4, your stored data will not automatically be ported.
Understanding changes to initialization
The Flutter SDK version 4 uses either a mobile key or a client-side ID as its credential, depending on the platform that you build for. If you are building for Windows, Mac, Linux, Android, or iOS, you must use a mobile key. If you are building for a web browser, you must use a client-side ID. In version 3, only a mobile key was accepted.
Your environment's mobile key and client-side ID are both available from the Environments list for each project.
You can set these credentials in the LAUNCHDARKLY_MOBILE_KEY
and LAUNCHDARKLY_CLIENT_SIDE_ID
environment variables, and then use the CredentialSource
helper to select your credential and provide it to your configuration. CredentialSource
expects one of the two environment variables to be set, but not both.
Here's how to provide credentials in your configuration options:
final config = LDConfig(CredentialSource.fromEnvironment, AutoEnvAttributes.enabled)
To learn more, read Get started in the Flutter SDK reference guide.
Understanding changes to LDConfig
In version 4 of the Flutter SDK, you can set the configuration options directly. The credential and automatic environment attributes configuration options are required. All other configuration options are optional and use default values if not set.
After you set the configuration, you can create a client using the configuration and a context.
Here's an example that configures the credential, automatic environment attributes, and evaluation reasons options:
final config = LDConfig(CredentialSource.fromEnvironment,AutoEnvAttributes.enabled,dataSourceConfig: DataSourceConfig(evaluationReasons: true),);
To learn more, read Configuration.
Understanding changes to LDClient and LDValue
In version 4 of the Flutter SDK, the LDClient
is no longer a singleton. Instead, you create a client of type LDClient
and then call functions on it. You must change your initialization code to accommodate this.
Here's how:
final config = LDConfig(CredentialSource.fromEnvironment,AutoEnvAttributes.enabled,dataSourceConfig: DataSourceConfig(evaluationReasons: true),);final context = LDContextBuilder().kind("user", "user-key-123abc").build();final client = LDClient(config, context);await client.start().timeout(const Duration(seconds: 30));
You can create multiple clients, each tied to separate credentials and separate environments, if you need to.
To learn more about initializing the client, read Get started in the Flutter SDK reference guide. To learn more about features supported by the client, read Supported features.
Most of the LDClient
methods are now synchronous, and do not need an await
in version 4 of the SDK. The close
, flush
, identify
, and clear
methods are asynchronous and still need an await
. However, the other LDClient
methods, including the *Variation
methods for evaluating flags, are now synchronous:
await client.identify(updatedContext);final variationResult = client.boolVariation(flagKey, false);await client.close();
Finally, all of the LDClient
methods that use parameters with the type LDValue
now require that you pass in an LDValue
explicitly. In version 3 of the SDK, you could pass in null
for these parameters. In version 4, you must use an LDValue
of null. To learn more, read LDValue
.
Understanding changes to connecting, listening, and fetching
In version 4 of the Flutter SDK, there are a few breaking changes to client methods for connecting, listening, and fetching.
Connection mode changes
It is rare to change the client's connection mode from the default. If you do set the client's connection mode on startup, the specifics have changed. In version 4, use the initialConnectionMode
configuration option:
final config = LDConfig(CredentialSource.fromEnvironment,AutoEnvAttributes.enabled,dataSourceConfig: DataSourceConfig(initialConnectionMode: ConnectionMode.offline // or .polling, or .streaming),);
To change the client's connection mode after it has started, use offline
:
// To switch an already-instantiated client to offline mode:client.offline(true);// To switch it back:client.offline(false);
To learn more, read Offline mode.
Subscribing to flag changes
To subscribe to feature flag changes, register listeners for change events from the SDK. The format for doing this has changed in version 4 of the SDK.
Here's how:
final sub = client.flagChanges.listen((changeEvent) {for(var flagKey in changeEvent.keys) {print(client.jsonVariation(flagKey, LDValue.ofString('default')));}});
To learn more, read Subscribing to flag changes.
Background fetch
If you are using the Flutter SDK version 4 on desktop or on the web, by default your application will continue to get updates. For example, if the end user minimizes your Windows app or moves to a different tab in their web browser, the SDK will continue to fetch flags in the background. You can change this behavior in your client configuration.
If you are using the Flutter SDK version 4 in a power-constrained situation, such as in a mobile application on iOS or Android, the SDK will not receive real-time events when backgrounded.
In the Flutter SDK version 3, the SDK did receive real-time events through background fetch on Android platforms, but not on iOS platforms. In version 4 of the SDK, this behavior has been standardized. Mobile applications do not receive real-time events when backgrounded.
Understanding changes to LDContext
The LDContext
builder now provides setters for primitive types, so that you do not need to create the LDValue
s yourself.
Starting in version 4, the Flutter SDK provides setBool
, setNum
, and setString
methods that you can use when you attributes to a context. Each setter also provides an optional parameter to indicate whether the attribute is private.
Here's how:
final context = LDContextBuilder().kind('user', 'user-key-123abc').setString('Sandy Smith').setNum('employeeID', 1234, private: true).setBool('fullTimeEmployee', true, private: true).build();
To learn more, read Context configuration and Private attributes.
Logging
Version 4 of the Flutter SDK now supports logging. By default, the SDK logs at the info
level with a tag of "LaunchDarkly." To change the logging, construct an LDLogger
and include it in your LDConfig
. You can change the log level, tag, and output destinations when you construct the logger.
Here's how:
final logger = LDLogger(level: LDLogLevel.warn);final config = LDConfig(CredentialSource.fromEnvironment,AutoEnvAttributes.enabled,logger: logger,);
To learn more, read Logging.