Skip to content

Flutter package for listening SMS code on Android, suggesting phone number, email, saving a credential.

License

Notifications You must be signed in to change notification settings

Tkko/flutter_smart_auth

Repository files navigation

Flutter Smart Auth From Tornike & Great Contributors

Pub package GitHub starts style: effective dart pub package

Flutter package for listening SMS code on Android, suggesting phone number, email, saving a credential.

If you need pin code input like shown below, take a look at Pinput package, SmartAuth is already integrated into it and you can build highly customizable input, that your designers can't even draw in Figma 🤭

Bonus tip: 🤫 Tell your PM that you need a week to implement the feature and chill with your friends meanwhile.

Note that only Android is supported, I faked other operating systems because other package is depended on this one and that package works on every system

Features:

  • Android Autofill
    • SMS Retriever API
    • SMS User Consent API
  • Showing Hint Dialog
  • Getting Saved Credential
  • Saving Credential
  • Deleting Credential

Support

PRs Welcome

Discord Channel

Example

Don't forget to give it a star ⭐

Getting Started

We should set project kotlin version to 1.8.0 or above because of the new requirement for sdk 34 RECEIVER_EXPORTED. Or we would get duplicate class error in different kotlin versions.

so in the android level build.gradle file update the kotlin version like below:

// android/build.gradle

buildscript {
    ext.kotlin_version = '1.8.0'
}

Create instance of SmartAuth

  final smartAuth = SmartAuth();

Get the App signature

  void getAppSignature() async {
    final res = await smartAuth.getAppSignature();
    debugPrint('Signature: $res');
  }

Get SMS code

  void getSmsCode() async {
    final res = await smartAuth.getSmsCode();
    if (res.succeed) {
      debugPrint('SMS: ${res.code}');
    } else {
      debugPrint('SMS Failure:');
    }
  }

The plugin automatically removes listeners after receiving the code, if not you can remove them by calling the removeSmsListener method

  void removeSmsListener() {
    smartAuth.removeSmsListener();
  }

Request hints to the user

  void requestHint() async {
    final res = await smartAuth.requestHint(
      isPhoneNumberIdentifierSupported: true,
      isEmailAddressIdentifierSupported: true,
      showCancelButton: true,
    );
    debugPrint('requestHint: $res');
  }

Request Hint

Get saved credential

  // identifier Url
  final accountType = 'https://developers.google.com';
  // Value you want to save, phone number or email for example
  final credentialId = 'Credential Id';
  final credentialName = 'Credential Name';
  final profilePictureUri = 'https://profilePictureUri.com';
  void getCredential() async {
    final res = await smartAuth.getCredential(
      accountType: accountType,
      showResolveDialog: true,
    );
    debugPrint('getCredentials: $res');
  }

Get Credential

Save credential

  void saveCredential() async {
    final res = await smartAuth.saveCredential(
      id: credentialId,
      name: credentialName,
      accountType: accountType,
      profilePictureUri: profilePictureUri,
    );
    debugPrint('saveCredentials: $res');
  }

Save Credential

Delete credential

  void deleteCredential() async {
    final res = await smartAuth.deleteCredential(
      id: credentialId,
      accountType: accountType,
    );
    debugPrint('removeCredentials: $res');
  }

API

getAppSignature

  /// This method outputs hash that is required for SMS Retriever API [https://developers.google.com/identity/sms-retriever/overview?hl=en]
  /// SMS must contain this hash at the end of the text
  /// Note that hash for debug and release if different
  Future<String?> getAppSignature()

getSmsCode

  /// Starts listening to SMS that contains the App signature [getAppSignature] in the text
  /// returns code if it matches with matcher
  /// More about SMS Retriever API [https://developers.google.com/identity/sms-retriever/overview?hl=en]
  ///
  /// If useUserConsentApi is true SMS User Consent API will be used [https://developers.google.com/identity/sms-retriever/user-consent/overview]
  /// Which shows confirmations dialog to user to confirm reading the SMS content
  Future<SmsCodeResult> getSmsCode({
    // used to extract code from SMS
    String matcher = _defaultCodeMatcher,
    // Optional parameter for User Consent API
    String? senderPhoneNumber,
    // if true SMS User Consent API will be used otherwise plugin will use SMS Retriever API
    bool useUserConsentApi = false,
  })

removeSmsListener

  /// Removes listener for [getSmsCode]
  Future<void> removeSmsListener()

  /// Disposes [getSmsCode] if useUserConsentApi is false listener
  Future<bool> removeSmsRetrieverListener()

  /// Disposes [getSmsCode] if useUserConsentApi is true listener
  Future<bool> removeSmsUserConsentListener()

requestHint

  /// Opens dialog of user emails and/or phone numbers
  /// More about hint request [https://developers.google.com/identity/smartlock-passwords/android/retrieve-hints]
  /// More about parameters [https://developers.google.com/android/reference/com/google/android/gms/auth/api/credentials/HintRequest.Builder]
  Future<Credential?> requestHint({
    // Enables returning credential hints where the identifier is an email address,
    // intended for use with a password chosen by the user.
    bool? isEmailAddressIdentifierSupported,
    // Enables returning credential hints where the identifier is a phone number,
    // intended for use with a password chosen by the user or SMS verification.
    bool? isPhoneNumberIdentifierSupported,
    // The list of account types (identity providers) supported by the app.
    // typically in the form of the associated login domain for each identity provider.
    String? accountTypes,
    // Enables button to add account
    bool? showAddAccountButton,
    // Enables button to cancel request
    bool? showCancelButton,
    // Specify whether an ID token should be acquired for hints, if available for the selected credential identifier.This is enabled by default;
    // disable this if your app does not use ID tokens as part of authentication to decrease latency in retrieving credentials and credential hints.
    bool? isIdTokenRequested,
    // Specify a nonce value that should be included in any generated ID token for this request.
    String? idTokenNonce,
    //Specify the server client ID for the backend associated with this app.
    // If a Google ID token can be generated for a retrieved credential or hint,
    // and the specified server client ID is correctly configured to be associated with the app,
    // then it will be used as the audience of the generated token. If a null value is specified,
    // the default audience will be used for the generated ID token.
    String? serverClientId,
  })

getCredential

  /// Tries to suggest a zero-click sign-in account. Only call this if your app does not currently know who is signed in.
  /// If zero-click suggestion fails app show dialog of credentials to choose from
  /// More about this https://developers.google.com/android/reference/com/google/android/gms/auth/api/credentials/CredentialsApi?hl=en#save(com.google.android.gms.common.api.GoogleApiClient,%20com.google.android.gms.auth.api.credentials.Credential)
  Future<Credential?> getCredential({
    // Identifier url, should be you App's website url
    String? accountType,
    String? serverClientId,
    String? idTokenNonce,
    bool? isIdTokenRequested,
    bool? isPasswordLoginSupported,
    // If we can't get credential without user interaction,
    // we can show dialog to prompt user to choose credential
    bool showResolveDialog = false,
  })

saveCredential

  /// Saves a credential that was used to sign in to the app. If disableAutoSignIn was previously called and the save operation succeeds,
  /// auto sign-in will be re-enabled if the user's settings permit this.
  ///
  /// Note: On Android O and above devices save requests that require showing a save confirmation may be cancelled
  /// in favor of the active Autofill service's save dialog.
  /// This behavior may be overridden by using Auth.AuthCredentialsOptions.Builder.forceEnableSaveDialog().
  /// Please see the overview documentation for more details on providing the best user experience when targeting Android O and above.
  /// More about this https://developers.google.com/android/reference/com/google/android/gms/auth/api/credentials/CredentialsApi?hl=en#save(com.google.android.gms.common.api.GoogleApiClient,%20com.google.android.gms.auth.api.credentials.Credential)
  Future<bool> saveCredential({
    // Value you want to save
    required String id,
    // Identifier url, should be you App's website url
    String? accountType,
    String? name,
    String? password,
    String? profilePictureUri,
  })

deleteCredential

  /// Deletes a credential that is no longer valid for signing into the app.
  /// More about this https://developers.google.com/android/reference/com/google/android/gms/auth/api/credentials/CredentialsApi?hl=en#save(com.google.android.gms.common.api.GoogleApiClient,%20com.google.android.gms.auth.api.credentials.Credential)
  Future<bool> deleteCredential({
    // Value you want to save
    required String id,
    // Identifier url, should be you App's website url
    String? accountType,
    String? name,
    String? password,
    String? profilePictureUri,
  })