Reputation: 1
I'm developing an application with GetX as state manager. I was able to manage the other aspects of the authentication but I got an error when it comes to recovering them. I tried everything but I still get this error. I would like to point out that the fetch from the firestore is done without problem. I want to solve this problem because I have to finish the application soon.
here is my AuthController
import 'dart:convert';
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sos_avc/models/user_model.dart';
class AuthController extends GetxController {
late FirebaseAuth _firebaseAuth;
late FirebaseFirestore _firebaseFirestore;
late FirebaseStorage _firebaseStorage;
Rx<User?> currentUser = Rx<User?>(FirebaseAuth.instance.currentUser);
UserModel? _userModel;
String? _uid;
Future<bool> isLoggedIn() async {
final user = _firebaseAuth.currentUser;
return user != null;
}
@override
void onInit() {
super.onInit();
_firebaseAuth = FirebaseAuth.instance;
_firebaseFirestore = FirebaseFirestore.instance;
_firebaseStorage = FirebaseStorage.instance;
}
@override
void onClose() {
super.onClose();
}
// Exemple de gestion des erreurs avec GetX
void showErrorSnackBar(String message) {
Get.snackbar(
'Erreur',
message,
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white,
);
}
Future<void> signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential userCredential =
await _firebaseAuth.signInWithEmailAndPassword(
email: email,
password: password,
);
currentUser.value = userCredential.user;
await getDataFromSP(); // Récupère les données utilisateur sauvegardées localement
} catch (e) {
showErrorSnackBar(e.toString());
}
}
Future<void> createUserWithEmailAndPassword(
String email, String password) async {
try {
UserCredential userCredential =
await _firebaseAuth.createUserWithEmailAndPassword(
email: email,
password: password,
);
currentUser.value = userCredential.user;
} catch (e) {
showErrorSnackBar(e.toString());
}
}
Future<void> signOut() async {
try {
await _firebaseAuth.signOut();
currentUser.value = null;
await clearUserDataFromSP();
} catch (e) {
showErrorSnackBar(e.toString());
}
}
Future<String> storeFileToStorage(String ref, File file) async {
try {
UploadTask uploadTask = _firebaseStorage.ref().child(ref).putFile(file);
TaskSnapshot snapshot = await uploadTask;
String downloadUrl = await snapshot.ref.getDownloadURL();
return downloadUrl;
} catch (e) {
showErrorSnackBar(e.toString());
return '';
}
}
@override
void dispose() {
super.dispose();
}
Future<void> resetPassword(String email) async {
try {
await _firebaseAuth.sendPasswordResetEmail(email: email);
} catch (e) {
showErrorSnackBar(e.toString());
}
}
Future<void> saveUserDataToFirebase({
required BuildContext context,
required UserModel userModel,
required File profilePic,
required Function onSuccess,
}) async {
try {
await storeFileToStorage("profilePic/$_uid", profilePic).then((value) {
userModel.profilePic = value;
userModel.createdAt = DateTime.now().millisecondsSinceEpoch.toString();
userModel.uid = _firebaseAuth.currentUser!.uid;
});
_userModel = userModel;
await _firebaseFirestore
.collection("customers")
.doc(_firebaseAuth.currentUser!.uid)
.set(userModel.toMap())
.then((value) {
onSuccess();
print(userModel);
});
await saveUserDataToSP();
} catch (e) {
showErrorSnackBar(e.toString());
}
}
Future<void> saveUserDataToSP() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString("user_model", jsonEncode(_userModel!.toMap()));
}
Future<void> getDataFromSP() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? data = prefs.getString("user_model");
if (data != null) {
_userModel = UserModel.fromMap(jsonDecode(data));
_uid = _userModel!.uid;
}
}
Future<void> clearUserDataFromSP() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove("user_model");
}
Future<void> getDataFromFirestore() async {
try {
DocumentSnapshot snapshot = await _firebaseFirestore
.collection("customers")
.doc(_firebaseAuth.currentUser!.uid)
.get();
_userModel = UserModel(
name: snapshot['name'],
email: snapshot['email'],
createdAt: snapshot['createdAt'],
address: snapshot['address'],
age: snapshot['age'],
uid: snapshot['uid'],
profilePic: snapshot['profilePic'],
phoneNumber: snapshot['phoneNumber'],
);
_uid = _userModel!.uid;
} catch (e) {
showErrorSnackBar(e.toString());
}
}
}
her is my usermodel
class UserModel {
String name;
String email;
String address;
String age;
String profilePic;
String createdAt;
int phoneNumber;
String uid;
UserModel({
required this.name,
required this.email,
required this.address,
required this.age,
required this.profilePic,
required this.createdAt,
required this.phoneNumber,
required this.uid,
});
// from map
factory UserModel.fromMap(Map<String, dynamic> map) {
return UserModel(
name: map['name'] ?? '',
email: map['email'] ?? '',
address: map['address'] ?? '',
age : map['age'] ?? '',
uid: map['uid'] ?? '',
phoneNumber: map['phoneNumber'] ?? '',
createdAt: map['createdAt'] ?? '',
profilePic: map['profilePic'] ?? '',
);
}
// to map
Map<String, dynamic> toMap() {
return {
"name": name,
"email": email,
"uid": uid,
"address": address,
"age" : age,
"profilePic": profilePic,
"phoneNumber": phoneNumber,
"createdAt": createdAt,
};
}
}
help me please
I tried to modify the function that it directly returns the user model like this
Future<UserModel?> getDataFromFirestore() async {
try {
DocumentSnapshot snapshot = await _firebaseFirestore
.collection("customers")
.doc(_firebaseAuth.currentUser!.uid)
.get();
if (snapshot.exists) {
return UserModel(
name: snapshot['name'],
email: snapshot['email'],
createdAt: snapshot['createdAt'],
address: snapshot['address'],
age: snapshot['age'],
uid: snapshot['uid'],
profilePic: snapshot['profilePic'],
phoneNumber: snapshot['phoneNumber'],
);
} else {
// Si le snapshot n'existe pas, vous pouvez renvoyer null ou une valeur par défaut.
return null;
}
} catch (e) {
showErrorSnackBar(e.toString());
return null; // En cas d'erreur, retournez null
}
}
in my UI. the profile page I wanted to retrieve it like this:
@override
void initState() {
super.initState();
loadUserData();
}
Future<void> loadUserData() async {
setState(() => isLoading = true);
final userModelFirestore = await authController.getDataFromFirestore();
if (userModelFirestore != null) {
setState(() {
_userModel = userModelFirestore;
isLoading = false;
});
} else {
final userModelSP = await authController.getDataFromSP();
setState(() {
_userModel = userModelSP;
isLoading = false;
});
}
}
Upvotes: 0
Views: 48