Closed razfazz closed 3 years ago
Thanks I tried fixing the trouble but it seems there are some bugs with the localization. https://github.com/aloisdeniel/flutter_sheet_localization/issues/32 As soon as this is updated I will try to update the plugin. Also some functions in firebase have changed yet again which is now the second time in a few months. I think I fixed all of that but don't want to update until I can fully test the app. Also updated the pubspec.yaml with :any for everything. You can see if these two changes fix it for you.
auth_controller.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:get/get.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:simple_gravatar/simple_gravatar.dart';
import 'package:flutter_starter/localizations.dart';
import 'package:flutter_starter/models/models.dart';
import 'package:flutter_starter/ui/auth/auth.dart';
import 'package:flutter_starter/ui/ui.dart';
import 'package:flutter_starter/ui/components/components.dart';
class AuthController extends GetxController {
static AuthController to = Get.find();
AppLocalizations_Labels labels;
TextEditingController nameController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _db = FirebaseFirestore.instance;
Rx<FirebaseUser> firebaseUser = Rx<FirebaseUser>();
Rx<UserModel> firestoreUser = Rx<UserModel>();
final RxBool admin = false.obs;
@override
void onReady() async {
//run every time auth state changes
ever(firebaseUser, handleAuthChanged);
firebaseUser.value = await getUser;
firebaseUser.bindStream(user);
super.onReady();
}
@override
void onClose() {
nameController?.dispose();
emailController?.dispose();
passwordController?.dispose();
super.onClose();
}
handleAuthChanged(_firebaseUser) async {
//get user data from firestore
if (_firebaseUser?.uid != null) {
firestoreUser.bindStream(streamFirestoreUser());
await isAdmin();
}
if (_firebaseUser == null) {
Get.offAll(SignInUI());
} else {
Get.offAll(HomeUI());
}
}
// Firebase user one-time fetch
Future<FirebaseUser> get getUser async => _auth.currentUser();
// Firebase user a realtime stream
Stream<FirebaseUser> get user => _auth.onAuthStateChanged;
//Streams the firestore user from the firestore collection
Stream<UserModel> streamFirestoreUser() {
print('streamFirestoreUser()');
if (firebaseUser?.value?.uid != null) {
return _db
.doc('/users/${firebaseUser.value.uid}')
.snapshots()
.map((snapshot) => UserModel.fromMap(snapshot.data()));
}
return null;
}
//get the firestore user from the firestore collection
Future<UserModel> getFirestoreUser() {
if (firebaseUser?.value?.uid != null) {
return _db.doc('/users/${firebaseUser.value.uid}').get().then(
(documentSnapshot) => UserModel.fromMap(documentSnapshot.data()));
}
return null;
}
//Method to handle user sign in using email and password
signInWithEmailAndPassword(BuildContext context) async {
final labels = AppLocalizations.of(context);
showLoadingIndicator();
try {
await _auth.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim());
emailController.clear();
passwordController.clear();
hideLoadingIndicator();
} catch (error) {
hideLoadingIndicator();
Get.snackbar(labels.auth.signInErrorTitle, labels.auth.signInError,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 7),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
// User registration using email and password
registerWithEmailAndPassword(BuildContext context) async {
final labels = AppLocalizations.of(context);
showLoadingIndicator();
try {
await _auth
.createUserWithEmailAndPassword(
email: emailController.text, password: passwordController.text)
.then((result) async {
print('uID: ' + result.uid);
print('email: ' + result.email);
//get photo url from gravatar if user has one
Gravatar gravatar = Gravatar(emailController.text);
String gravatarUrl = gravatar.imageUrl(
size: 200,
defaultImage: GravatarImage.retro,
rating: GravatarRating.pg,
fileExtension: true,
);
//create the new user object
UserModel _newUser = UserModel(
uid: result.uid,
email: result.email,
name: nameController.text,
photoUrl: gravatarUrl);
//create the user in firestore
_createUserFirestore(_newUser, result);
emailController.clear();
passwordController.clear();
hideLoadingIndicator();
});
} catch (error) {
hideLoadingIndicator();
Get.snackbar(labels.auth.signUpErrorTitle, error.message,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 10),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
//handles updating the user when updating profile
Future<void> updateUser(BuildContext context, UserModel user, String oldEmail,
String password) async {
final labels = AppLocalizations.of(context);
try {
showLoadingIndicator();
await _auth
.signInWithEmailAndPassword(email: oldEmail, password: password)
.then((_firebaseUser) {
_firebaseUser
.updateEmail(user.email)
.then((value) => _updateUserFirestore(user, _firebaseUser));
});
hideLoadingIndicator();
Get.snackbar(labels.auth.updateUserSuccessNoticeTitle,
labels.auth.updateUserSuccessNotice,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 5),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
} on PlatformException catch (error) {
//List<String> errors = error.toString().split(',');
// print("Error: " + errors[1]);
hideLoadingIndicator();
print(error.code);
String authError;
switch (error.code) {
case 'ERROR_WRONG_PASSWORD':
authError = labels.auth.wrongPasswordNotice;
break;
default:
authError = labels.auth.unknownError;
break;
}
Get.snackbar(labels.auth.wrongPasswordNoticeTitle, authError,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 10),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
//updates the firestore user in users collection
void _updateUserFirestore(UserModel user, FirebaseUser _firebaseUser) {
_db.doc('/users/${_firebaseUser.uid}').update(user.toJson());
update();
}
//create the firestore user in users collection
void _createUserFirestore(UserModel user, FirebaseUser _firebaseUser) {
_db.doc('/users/${_firebaseUser.uid}').set(user.toJson());
update();
}
//password reset email
Future<void> sendPasswordResetEmail(BuildContext context) async {
final labels = AppLocalizations.of(context);
showLoadingIndicator();
try {
await _auth.sendPasswordResetEmail(email: emailController.text);
hideLoadingIndicator();
Get.snackbar(
labels.auth.resetPasswordNoticeTitle, labels.auth.resetPasswordNotice,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 5),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
} catch (error) {
hideLoadingIndicator();
Get.snackbar(labels.auth.resetPasswordFailed, error.message,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 10),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
//check if user is an admin user
isAdmin() async {
await getUser.then((user) async {
DocumentSnapshot adminRef =
await _db.collection('admin').doc(user?.uid).get();
if (adminRef.exists) {
admin.value = true;
} else {
admin.value = false;
}
update();
});
}
// Sign out
Future<void> signOut() {
nameController.clear();
emailController.clear();
passwordController.clear();
return _auth.signOut();
}
}
This should now be resolved. Let me know if you still have issues.
just a note about modification to auth_controller.
updated auth_controller.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:get/get.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:simple_gravatar/simple_gravatar.dart';
import 'package:flutter_starter/localizations.dart';
import 'package:flutter_starter/models/models.dart';
import 'package:flutter_starter/ui/auth/auth.dart';
import 'package:flutter_starter/ui/ui.dart';
import 'package:flutter_starter/ui/components/components.dart';
class AuthController extends GetxController {
static AuthController to = Get.find();
AppLocalizations_Labels labels;
TextEditingController nameController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _db = FirebaseFirestore.instance;
Rx<User> firebaseUser = Rx<User>();
Rx<UserModel> firestoreUser = Rx<UserModel>();
final RxBool admin = false.obs;
@override
void onReady() async {
//run every time auth state changes
ever(firebaseUser, handleAuthChanged);
firebaseUser.value = await getUser;
firebaseUser.bindStream(user);
super.onReady();
}
@override
void onClose() {
nameController?.dispose();
emailController?.dispose();
passwordController?.dispose();
super.onClose();
}
handleAuthChanged(_firebaseUser) async {
//get user data from firestore
if (_firebaseUser?.uid != null) {
firestoreUser.bindStream(streamFirestoreUser());
await isAdmin();
}
if (_firebaseUser == null) {
Get.offAll(SignInUI());
} else {
Get.offAll(HomeUI());
}
}
// Firebase user one-time fetch
Future<User> get getUser async => _auth.currentUser;
// Firebase user a realtime stream
Stream<User> get user => _auth.authStateChanges();
//Streams the firestore user from the firestore collection
Stream<UserModel> streamFirestoreUser() {
print('streamFirestoreUser()');
if (firebaseUser?.value?.uid != null) {
return _db
.doc('/users/${firebaseUser.value.uid}')
.snapshots()
.map((snapshot) => UserModel.fromMap(snapshot.data()));
}
return null;
}
//get the firestore user from the firestore collection
Future<UserModel> getFirestoreUser() {
if (firebaseUser?.value?.uid != null) {
return _db.doc('/users/${firebaseUser.value.uid}').get().then(
(documentSnapshot) => UserModel.fromMap(documentSnapshot.data()));
}
return null;
}
//Method to handle user sign in using email and password
signInWithEmailAndPassword(BuildContext context) async {
final labels = AppLocalizations.of(context);
showLoadingIndicator();
try {
await _auth.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim());
emailController.clear();
passwordController.clear();
hideLoadingIndicator();
} catch (error) {
hideLoadingIndicator();
Get.snackbar(labels.auth.signInErrorTitle, labels.auth.signInError,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 7),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
// User registration using email and password
registerWithEmailAndPassword(BuildContext context) async {
final labels = AppLocalizations.of(context);
showLoadingIndicator();
try {
await _auth
.createUserWithEmailAndPassword(
email: emailController.text, password: passwordController.text)
.then((result) async {
print('uID: ' + result.user.uid);
print('email: ' + result.user.email);
//get photo url from gravatar if user has one
Gravatar gravatar = Gravatar(emailController.text);
String gravatarUrl = gravatar.imageUrl(
size: 200,
defaultImage: GravatarImage.retro,
rating: GravatarRating.pg,
fileExtension: true,
);
//create the new user object
UserModel _newUser = UserModel(
uid: result.user.uid,
email: result.user.email,
name: nameController.text,
photoUrl: gravatarUrl);
//create the user in firestore
_createUserFirestore(_newUser, result.user);
emailController.clear();
passwordController.clear();
hideLoadingIndicator();
});
} catch (error) {
hideLoadingIndicator();
Get.snackbar(labels.auth.signUpErrorTitle, error.message,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 10),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
//handles updating the user when updating profile
Future<void> updateUser(BuildContext context, UserModel user, String oldEmail,
String password) async {
final labels = AppLocalizations.of(context);
try {
showLoadingIndicator();
await _auth
.signInWithEmailAndPassword(email: oldEmail, password: password)
.then((_firebaseUser) {
_firebaseUser.user
.updateEmail(user.email)
.then((value) => _updateUserFirestore(user, _firebaseUser.user));
});
hideLoadingIndicator();
Get.snackbar(labels.auth.updateUserSuccessNoticeTitle,
labels.auth.updateUserSuccessNotice,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 5),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
} on PlatformException catch (error) {
//List<String> errors = error.toString().split(',');
// print("Error: " + errors[1]);
hideLoadingIndicator();
print(error.code);
String authError;
switch (error.code) {
case 'ERROR_WRONG_PASSWORD':
authError = labels.auth.wrongPasswordNotice;
break;
default:
authError = labels.auth.unknownError;
break;
}
Get.snackbar(labels.auth.wrongPasswordNoticeTitle, authError,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 10),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
//updates the firestore user in users collection
void _updateUserFirestore(UserModel user, User _firebaseUser) {
_db.doc('/users/${_firebaseUser.uid}').update(user.toJson());
update();
}
//create the firestore user in users collection
void _createUserFirestore(UserModel user, User _firebaseUser) {
_db.doc('/users/${_firebaseUser.uid}').set(user.toJson());
update();
}
//password reset email
Future<void> sendPasswordResetEmail(BuildContext context) async {
final labels = AppLocalizations.of(context);
showLoadingIndicator();
try {
await _auth.sendPasswordResetEmail(email: emailController.text);
hideLoadingIndicator();
Get.snackbar(
labels.auth.resetPasswordNoticeTitle, labels.auth.resetPasswordNotice,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 5),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
} catch (error) {
hideLoadingIndicator();
Get.snackbar(labels.auth.resetPasswordFailed, error.message,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 10),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
//check if user is an admin user
isAdmin() async {
await getUser.then((user) async {
DocumentSnapshot adminRef =
await _db.collection('admin').doc(user?.uid).get();
if (adminRef.exists) {
admin.value = true;
} else {
admin.value = false;
}
update();
});
}
// Sign out
Future<void> signOut() {
nameController.clear();
emailController.clear();
passwordController.clear();
return _auth.signOut();
}
}
When running your sample project i receive the following error.
Because firebase_auth >=0.18.4 <=0.18.4 depends on firebase_auth_web ^0.3.2+2 and firebase_auth ^0.18.4+1 depends on firebase_auth_web ^0.3.2+3, firebase_auth ^0.18.4 requires firebase_auth_web ^0.3.2+2. (1) So, because firebase_auth >=0.18.3+1 <0.18.4 depends on firebase_auth_web ^0.3.2+1, firebase_auth ^0.18.3+1 requires firebase_auth_web ^0.3.2+1.
flutter_localizations from sdk. So, because flutter_starter depends on both flutter_localizations any from sdk and firebase_auth ^0.18.0+1, version solving failed. Running "flutter pub get" in flutter_starter-master...
pub get failed (1; So, because flutter_starter depends on both flutter_localizations any from sdk and firebase_auth ^0.18.0+1, version solving failed.)