Firebase Auth Client

PHOTO EMBED

Tue Jul 09 2024 20:07:28 GMT+0000 (Coordinated Universal Time)

Saved by @Samuel1347 #flutter #dart #firebase

import 'dart:developer';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:easy_localization/easy_localization.dart';

import '../../features/auth/core/models/token_response_model.dart';
import 'api_exceptions.dart';

abstract class FirebaseAuthApiClient {

  Future<void> signIn(String phoneNumber, Function(String) codeSent);

  Future<TokenResponseModel> verifyOTP(String verificationId, String smsCode);
  Future<void> signUpWithOTP(String phoneNumber, Function(String) codeSent);
}

class FirebaseAuthApiClientImpl extends FirebaseAuthApiClient {
  final FirebaseAuth _auth;

  FirebaseAuthApiClientImpl(this._auth);

  @override
  Future<void> signIn(String phoneNumber, Function(String) codeSent) async {
    try {
      final phone = "+$phoneNumber";
      log('Signing in with phone number: $phone');
      await _auth.verifyPhoneNumber(
        phoneNumber: phone,
        verificationCompleted: (PhoneAuthCredential credential) async {
          await _auth.signInWithCredential(credential);
          print("Credential $credential");
        },
        verificationFailed: (FirebaseAuthException e) {
          print("Error $e");
          throw _handleError(e, tr('otpSignUpError'));
        },
        codeSent: (String verificationId, int? resendToken) {
          print("Code send code send ");
          codeSent(verificationId);
        },
        codeAutoRetrievalTimeout: (String verificationId) {},
      );
    } catch (e) {
      log('Sign in error: $e');
      throw _handleError(e, tr('otpSignInError'));
    }
  }

  @override
  Future<TokenResponseModel> verifyOTP(
      String verificationId, String smsCode) async {
    try {
      PhoneAuthCredential credential = PhoneAuthProvider.credential(
        verificationId: verificationId,
        smsCode: smsCode,
      );
      print("Credenrial $credential");
      print("verificationId $verificationId smsCode $smsCode ");
      final data = await _auth.signInWithCredential(credential);

      final token = await data.user!.getIdToken();


      if(token == null) {

      throw _handleError( ExceptionWithMessage(tr('tokenNotFound')), tr('tokenNotFound'));
      }
      print("Token $token");


      return TokenResponseModel.fromJson(data, token);
    } catch (e) {
      throw _handleError(e, tr('otpVerificationError'));
    }
  }

  @override
  Future<void> signUpWithOTP(
      String phoneNumber, Function(String) codeSent) async {
    try {
      final phone = "+$phoneNumber";
      print(phone);
      await _auth.verifyPhoneNumber(
        phoneNumber: phone,
        verificationCompleted: (PhoneAuthCredential credential) async {
          await _auth.signInWithCredential(credential);
          print("Credential $credential");
        },
        verificationFailed: (FirebaseAuthException e) {
          print("Error $e");
          throw _handleError(e, tr('otpSignUpError'));
        },
        codeSent: (String verificationId, int? resendToken) {
          codeSent(verificationId);
        },
        codeAutoRetrievalTimeout: (String verificationId) {},
      );
    } catch (e) {
      throw _handleError(e, tr('otpSignUpError'));
    }
  }

  Exception _handleError(dynamic error, String defaultMessage) {
    if (error is FirebaseAuthException) {
      switch (error.code) {
        case 'invalid-verification-code':
          return ExceptionWithMessage(tr('invalidVerificationCode'));
        case 'user-disabled':
          return UnauthorisedException();
        case 'too-many-requests':
          return ExceptionWithMessage(tr('tooManyRequests'));
        case 'operation-not-allowed':
          return ExceptionWithMessage(tr('operationNotAllowed'));
        default:
          return ExceptionWithMessage('$defaultMessage: ${error.message}');
      }
    }
    return ExceptionWithMessage(defaultMessage);
  }
}
content_copyCOPY