Last active
July 6, 2020 03:51
-
-
Save erluxman/fe93be1cbd25293c8f855ceaf4cb3b0f to your computer and use it in GitHub Desktop.
FirebaseAuthRepo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:apple_sign_in/apple_sign_in.dart'; | |
import 'package:firebase_auth/firebase_auth.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
import 'package:flutter_facebook_login/flutter_facebook_login.dart'; | |
import 'package:google_sign_in/google_sign_in.dart'; | |
import 'package:rxdart/rxdart.dart'; | |
import 'package:toast_badge/toast_badge.dart'; | |
/* Add the following dependencies to fully use it | |
firebase_auth: ^0.16.1 | |
flutter_facebook_login: ^3.0.0 | |
google_sign_in: ^4.5.1 | |
firebase_core: ^0.4.5 | |
apple_sign_in: ^0.1.0 | |
rxdart | |
toast_badge | |
*/ | |
class AuthRepo with ChangeNotifier { | |
BehaviorSubject<FirebaseUser> _userStream = BehaviorSubject(); | |
BehaviorSubject<bool> _verificationCodeSent = BehaviorSubject(); | |
String _verificationId; | |
AuthRepo() { | |
_init(); | |
} | |
Stream<FirebaseUser> user() => _userStream; | |
Stream<bool> verificationCodeSent() => _verificationCodeSent; | |
_init() async { | |
print("user stream initialized"); | |
_userStream.add(await FirebaseAuth.instance.currentUser()); | |
print(_userStream.value); | |
} | |
Future<void> updateDisplayName(String newName) async { | |
//Have to call it twice for name coz for some strange reason, name does not update in one call. | |
await _updateFirebaseProfile(displayName: newName); | |
await _updateFirebaseProfile(displayName: newName); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
Future<void> updateImageUrl(String newImageUrl) async { | |
await _updateFirebaseProfile(photoUrl: newImageUrl); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
Future<void> _updateFirebaseProfile({String displayName, String photoUrl}) async { | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
UserUpdateInfo newInfo = UserUpdateInfo(); | |
newInfo.displayName = displayName ?? user.displayName; | |
newInfo.photoUrl = photoUrl ?? user.photoUrl; | |
return await user.updateProfile(newInfo); | |
} | |
sendVerificationCode(String phone) async { | |
await FirebaseAuth.instance.verifyPhoneNumber( | |
phoneNumber: phone, | |
timeout: Duration(minutes: 1), | |
verificationCompleted: completed(), | |
verificationFailed: failed(), | |
codeSent: codeSent(), | |
codeAutoRetrievalTimeout: autoTimeout(), | |
); | |
} | |
submitVerificationCode(String verificationCode) async { | |
print("login with phone Otp:$verificationCode and verification code $verificationCode"); | |
AuthCredential cred = | |
PhoneAuthProvider.getCredential(verificationId: _verificationId, smsCode: verificationCode); | |
AuthResult result = await FirebaseAuth.instance.signInWithCredential(cred); | |
print("Auth result : ${result.user.phoneNumber}"); | |
ToastBadge.show("Login Success"); | |
await Future.delayed(Duration(seconds: 2)); | |
FirebaseUser user = await FirebaseAuth.instance?.currentUser(); | |
_userStream.add(user); | |
_verificationId = null; | |
_verificationCodeSent.add(false); | |
print("user's phone number ${user?.phoneNumber}"); | |
print("user is verified ${user?.phoneNumber}"); | |
} | |
logOut() async { | |
_userStream.add(null); | |
ToastBadge.show("Logout Success"); | |
await Future.delayed(Duration(seconds: 2)); | |
FirebaseAuth.instance.signOut(); | |
_userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
PhoneVerificationCompleted completed() => (AuthCredential cred) async { | |
print("verification completed ${cred.toString()}"); | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
print("phone number : ${user.phoneNumber}"); | |
}; | |
PhoneVerificationFailed failed() => (AuthException exception) { | |
print("verification failed ${exception.message}"); | |
}; | |
PhoneCodeSent codeSent() => (String code, [int force]) { | |
print("verification code sent $code"); | |
_verificationId = code; | |
ToastBadge.show("Code Sent"); | |
_verificationCodeSent.add(true); | |
}; | |
PhoneCodeAutoRetrievalTimeout autoTimeout() => (String verificationID) { | |
print("auto retribal timeout $verificationID"); | |
}; | |
@override | |
void dispose() { | |
super.dispose(); | |
_userStream.close(); | |
_verificationCodeSent.close(); | |
} | |
loginWithFacebook() async { | |
final AuthResult authResult = | |
await FirebaseAuth.instance.signInWithCredential(await _getFbCredential()); | |
final FirebaseUser user = authResult.user; | |
_userStream.add(user); | |
} | |
loginWithGoogle() async { | |
final FirebaseAuth _auth = FirebaseAuth.instance; | |
final AuthCredential credential = await _getGoogleCredential(); | |
final AuthResult result = await _auth.signInWithCredential(credential); | |
final FirebaseUser user = result.user; | |
_userStream.add(user); | |
} | |
Future<void> addGoogle() async { | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
AuthCredential googleauthCredential = await _getGoogleCredential(); | |
await user.linkWithCredential(googleauthCredential); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
loginWithApple() async { | |
final FirebaseAuth _auth = FirebaseAuth.instance; | |
final AuthCredential credential = await _getAppleCredential(); | |
if (credential == null) return; | |
final AuthResult result = await _auth.signInWithCredential(credential); | |
final FirebaseUser user = result.user; | |
_userStream.add(user); | |
} | |
Future<void> addApple() async { | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
AuthCredential appleCreds = await _getAppleCredential(); | |
await user.linkWithCredential(appleCreds); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
Future<AuthCredential> _getGoogleCredential() async { | |
final GoogleSignIn _googleSignIn = GoogleSignIn(); | |
final GoogleSignInAccount googleUser = await _googleSignIn.signIn(); | |
final GoogleSignInAuthentication googleAuth = await googleUser.authentication; | |
return GoogleAuthProvider.getCredential( | |
accessToken: googleAuth.accessToken, | |
idToken: googleAuth.idToken, | |
); | |
} | |
Future<AuthCredential> _getAppleCredential() async { | |
final AuthorizationResult result = await AppleSignIn.performRequests([ | |
AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName]) | |
]); | |
if (result.status != AuthorizationStatus.authorized) return null; | |
final AppleIdCredential appleIdCredential = result.credential; | |
final OAuthProvider oAuthProvider = OAuthProvider(providerId: "apple.com"); | |
return oAuthProvider.getCredential( | |
idToken: String.fromCharCodes(appleIdCredential.identityToken), | |
accessToken: String.fromCharCodes(appleIdCredential.authorizationCode), | |
); | |
} | |
Future<AuthCredential> _getFbCredential() async { | |
FacebookLoginResult result = await FacebookLogin().logIn(['email']); | |
if (result.accessToken == null) { | |
await FacebookLogin().logOut(); | |
print("fbloginerror" + result.errorMessage); | |
result = await FacebookLogin().logIn(['email']); | |
if (result.accessToken == null) { | |
ToastBadge.show(result.errorMessage, mode: ToastMode.ERROR); | |
} | |
} | |
return FacebookAuthProvider.getCredential(accessToken: result.accessToken.token); | |
} | |
loginWithEmailPass(String email, String password) async { | |
AuthCredential emailCred = await _getEmailCredential(email, password).catchError( | |
(error) { | |
print("caught error 1 $error"); | |
ToastBadge.show(error.toString(), mode: ToastMode.ERROR); | |
}, | |
); | |
FirebaseAuth.instance.signInWithCredential(emailCred).then((AuthResult authResult) { | |
final FirebaseUser user = authResult.user; | |
_userStream.add(user); | |
}).catchError( | |
(Object e) { | |
if (e is PlatformException && e.code == "ERROR_USER_NOT_FOUND") { | |
FirebaseAuth.instance | |
.createUserWithEmailAndPassword(email: email, password: password) | |
.then((AuthResult authResult) { | |
final FirebaseUser user = authResult.user; | |
_userStream.add(user); | |
}); | |
} | |
ToastBadge.show(e.toString(), mode: ToastMode.ERROR); | |
print("caught error 2 $e"); | |
}, | |
); | |
} | |
Future<AuthCredential> _getEmailCredential(String email, String password) async => | |
EmailAuthProvider.getCredential(email: email, password: password); | |
Future<void> addFacebook() async { | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
AuthCredential fbAuthCredential = await _getFbCredential(); | |
await user.linkWithCredential(fbAuthCredential); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
Future<void> removeFacebook() async { | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
await user.unlinkFromProvider(FacebookAuthProvider.providerId); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
Future<void> removeProvider(String providerID) async { | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
List<UserInfo> providers = | |
user.providerData.where((UserInfo provider) => provider.providerId != "firebase").toList(); | |
providers.removeWhere((UserInfo info) => info.providerId == providerID); | |
//There needs to be at least one firebase Id and another provider Id (email/fb/google) | |
if (providers.length < 1) { | |
ToastBadge.show("Needs at least one way to login to your account", mode: ToastMode.ERROR); | |
return; | |
} else { | |
await user.unlinkFromProvider(providerID); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
} | |
Future<void> removeGoogle() async { | |
FirebaseUser user = await FirebaseAuth.instance.currentUser(); | |
await user.unlinkFromProvider(GoogleAuthProvider.providerId); | |
return _userStream.add(await FirebaseAuth.instance.currentUser()); | |
} | |
Future<void> sendForgotPasswordEmail(String email) async { | |
return await FirebaseAuth.instance.sendPasswordResetEmail(email: email); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment