Upgrade guide
Amplify Flutter v2 has changes in Auth, Analytics, Storage, GraphQL API & DataStore that may require migration when upgrading from v1.
Auth
Time Based One Time Password (TOTP) Exception Handling
In Amplify Flutter v1, Amplify.Auth.verifyTotpSetup()
throws an EnableSoftwareTokenMfaException
if the provided code was incorrect. In Amplify Flutter v2 a CodeMismatchException
is thrown.
Auth Flow in Amplify Config
In Amplify Flutter v1, the value of “authenticationFlowType”
from the Amplify configuration object is used as the default AuthenticationFlowType
if none is provided when calling Amplify.Auth.signIn()
.
In Amplify Flutter v2, default type is AuthenticationFlowType.userSrpAuth
. To change the authentication flow type, you can provide a value in the sign in options under options
parameter..
await Amplify.Auth.signIn( username: 'username', password: 'password', options: const SignInOptions( pluginOptions: CognitoSignInPluginOptions( authFlowType: AuthenticationFlowType.userSrpAuth, ), ),)
Analytics
Configuration of autoFlushEventsInterval
In Amplify Flutter v1, the autoFlushEventsInterval
value was configured manually in the amplifyconfiguration.dart
file. In Amplify Flutter v2, the autoFlushEventsInterval
value is not read from amplifyconfiguration.dart
but instead is passed directly to the AmplifyAnalyticsPinpoint()
constructor under the AnalyticsPinpointPluginOptions
. The default value for autoFlushEventsInterval
remains at 30 seconds, consistent with the behavior in Amplify Flutter v1.
Storage
key
and StorageAccessLevel
have been replaced by StoragePath
In Amplify Flutter v1, files operations were performed based on a key
and an AccessLevel
. Amplify translated these values to a full file path. The AccessLevel
(guest, protected, or private) determined what prefix to use (“public/”
, “protected/<user_identity_id>/”
, or “private/<user_identity_id>/”
). Amplify Flutter v1 forms the full path using the prefix and the provided key.
Amplify Flutter v2 allows for full control of the path of the storage object. Storage paths can be constructed either from a static string or from the current users identity id using the StoragePath
class.
To migrate from v1 to v2, replace all uses of key
with path
and remove uses of StorageAccessLevel
. The path should include the prefix that was previously added by Amplify automatically.
Example Migration for Public Files
// upload file to "public/file.txt" in Amplify Flutter v1Amplify.Storage.uploadFile( localFile: file, key: 'file.txt', options: StorageUploadFileOptions( accessLevel: StorageAccessLevel.guest, ),);
// upload file to "public/file.txt" in Amplify Flutter v2Amplify.Storage.uploadFile( localFile: file, path: const StoragePath.fromString("public/file.txt"),);
Example Migration for Protected Files
// upload file to "protected/<user_identity_id>/file.txt" in Amplify Flutter v1Amplify.Storage.uploadFile( localFile: file, key: 'file.txt', options: StorageUploadFileOptions( accessLevel: StorageAccessLevel.protected, ),);
// upload file to "protected/<user_identity_id>/file.txt" in Amplify Flutter v2Amplify.Storage.uploadFile( localFile: file, path: StoragePath.fromIdentityId( (identityId) => "protected/$identityId/file.txt", ), );
Example Migration for Private Files
// upload file to "private/<user_identity_id>/file.txt" in Amplify Flutter v1Amplify.Storage.uploadFile( localFile: file, key: 'file.txt', options: StorageUploadFileOptions( accessLevel: StorageAccessLevel.private, ),);
// upload file to "private/<user_identity_id>/file.txt" in Amplify Flutter v2Amplify.Storage.uploadFile( localFile: file, path: StoragePath.fromIdentityId( (identityId) => "private/$identityId/file.txt", ), );
Prefix Resolver has been removed
With the introduction of StoragePath
, there is no need for a prefix resolver. Simply specify the full path when constructing the StoragePath
.
Delimiter has been moved to the List API Options
In Amplify Flutter v1 AmplifyStorageS3
accepted a delimiter
option. This was used in list operations to determine sub paths. This option is now available as part of the List API options.
final result = Amplify.Storage.list( path: const StoragePath.fromString('public/album/'), options: const StorageListOptions( pageSize: 50, pluginOptions: S3ListPluginOptions( excludeSubPaths: true, delimiter: '/' ), ),);
DataStore
Configuration
In Amplify Flutter v1, the AmplifyDataStore()
constructor allows for the customization of the plugin through optional parameters such as errorHandler, conflictHandler, syncExpression, syncInterval, syncMaxRecords, syncPageSize, and authModeStrategy. In Amplify Flutter v2, these parameters have been relocated under DataStorePluginOptions, with default values that mirror those of Amplify Flutter v1.
Models & Query Predicates (GraphQL API & DataStore)
Configuration
In Amplify Flutter v1, the AmplifyAPI()
constructor accepts optional parameters such as authProviders, baseHttpClient, modelProvider, and subscriptionOptions. In Amplify Flutter v2, these parameters have been relocated to APIPluginOptions
.
Generated Models
Model.fromJson()
Amplify Flutter v2 now decodes AppSync GraphQL responses in their original shape (#816). In doing so, we’ve removed the previous transformations that happened after receiving an AppSync response. This requires data Models to be regenerated with the latest Amplify CLI. After upgrading to Amplify Flutter v2 please run the following:
$ amplify upgrade# from the root of your Flutter project$ amplify codegen models
Model.getId()
Amplify Flutter v2 removes all usage of the generated Model.getId()
method. Replace all instances of Model.getId()
and with Model.modelIdentifier
.
Nested Model Query Predicates
Query predicates for nested model relationships when passing Model.id for equal and not equal operations are no longer supported. Please update your query predicates to use Model.modelIdentifier, for example:
- Post.BLOG.eq(blog1.id)+ Post.BLOG.eq(blog1.modelIdentifier)
Or
- Post.BLOG.eq("1234") => + Post.BLOG.eq(BlogModelIdentifier(id: "1234"))
Support For Only Custom Primary Key Enabled Back-Ends
Amplify Flutter V2 no longer supports the Amplify CLI feature flag respectprimarykeyattributesonconnectionfield
to be disabled.
If this feature flag is already enabled in your current project you can skip this section.
graphql.schema | Feature Flag On | Feature Flag off |
---|---|---|
has @primaryKey | No further action required | Start at step 1. |
no @primaryKey | No further action required | Skip to step 4. |
If the feature flag is turned off AND your model schema has the @primaryKey
annotation, please follow these migration steps.
If the feature flag is turned off, but your graphql.schema
does not contain references to @primaryKey
, jump to step 4.
- Remove
@primaryKey
references from yourgraphql.schema
- Run
$ amplify push
- Run
$ amplify codegen models
- Enabled the feature flag:
- Locate
amplify/cli.json
inside your project - Enable the feature flag:
- Locate
"features": { "graphqltransformer": { ... "respectprimarykeyattributesonconnectionfield": true, ... },}
- Run
$ amplify push
- Run
$ amplify codegen models