signInWithNativeAuth method
Sign in with a native provider (Google or Apple) using Amplify Hosted UI.
provider must be "google" or "apple".
On success, persists tokens via TokenStorage and returns a map including
localStorageItems for WebView injection (CognitoIdentityServiceProvider keys).
Requires Remit2AnyAuth.configureAmplify (or equivalent) before the first call.
Implementation
Future<Map<String, dynamic>> signInWithNativeAuth(String provider) async {
final authProvider = provider.toLowerCase() == 'apple'
? AuthProvider.apple
: provider.toLowerCase() == 'google'
? AuthProvider.google
: null;
if (authProvider == null) {
return {
'success': false,
'isSignedIn': false,
'error': 'Invalid provider: use "google" or "apple"',
};
}
try {
await _ensureAmplifyConfigured();
} catch (e) {
debugPrint('AuthService: Amplify configure failed: $e');
return {
'success': false,
'isSignedIn': false,
'error': 'Amplify configuration failed: ${e.toString()}',
};
}
try {
final result = await Amplify.Auth.signInWithWebUI(provider: authProvider);
final step = result.nextStep;
final resultJson = {
'isSignedIn': result.isSignedIn,
'nextStep': {
'signInStep': step.signInStep.toString(),
'additionalInfo': step.additionalInfo,
'missingAttributes': step.missingAttributes,
},
};
debugPrint(
'AuthService: signInWithWebUI result: ${jsonEncode(resultJson)}');
if (!result.isSignedIn) {
return {'success': false, 'isSignedIn': false};
}
final poolTokens = await _fetchCognitoUserPoolTokens();
if (poolTokens == null) {
return {
'success': false,
'isSignedIn': true,
'error': 'Could not fetch session tokens',
};
}
final access = poolTokens.accessToken.raw;
final idTok = poolTokens.idToken.raw;
final refresh = poolTokens.refreshToken;
await TokenStorage.saveAuthProvider(provider);
final lastAuthUser = poolTokens.username.isNotEmpty
? poolTokens.username
: (_getLastAuthUserFromAccessToken(access) ?? poolTokens.userId);
debugPrint('AuthService: lastAuthUser: $lastAuthUser');
final cognitoUserId = lastAuthUser;
final appClientId = Remit2AnyEnvironmentConfig.userPoolClientId;
final cognitoStoragePrefix =
'CognitoIdentityServiceProvider.$appClientId.$cognitoUserId';
final cognitoLastAuthUserKey =
'CognitoIdentityServiceProvider.$appClientId.LastAuthUser';
final Map<String, String> localStorageItems = {};
if (cognitoUserId.isNotEmpty) {
localStorageItems[cognitoLastAuthUserKey] = cognitoUserId;
localStorageItems['$cognitoStoragePrefix.idToken'] = idTok;
localStorageItems['$cognitoStoragePrefix.accessToken'] = access;
if (refresh.isNotEmpty) {
localStorageItems['$cognitoStoragePrefix.refreshToken'] = refresh;
}
}
return localStorageItems;
} on AuthException catch (e) {
debugPrint('AuthService: $provider sign-in error: ${e.message}');
return {
'success': false,
'isSignedIn': false,
'error': e.message,
};
} catch (e) {
debugPrint('AuthService: $provider sign-in error: $e');
return {
'success': false,
'isSignedIn': false,
'error': e.toString(),
};
}
}