GAEL SASSAN
GAEL SASSAN

Reputation: 1

Flutter NullSafety error With GetX when fetch data

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

Answers (0)

Related Questions