How to match Firebase User UID with Firestore Doc ID - Flutter

Question

Asked by Saw T on November 12, 2021 (source).

I am new to flutter. So Please kindly bear with me.

I am creating a Real Estate App using Firebase and Provider. I have two root Collections (1) "users" and (2) "properties"

I would like to achieve one specific task. Although it seems like a simple task, yet I am still unable to solve it. The task is to store Firebase User UID as Firestore Document ID of the rool Collection called "users" when the user sign up.

The problem I am having is the Firestore Document ID is automatically generated and its not Firebase User UID. Plus the field for userId appears null in Firestore. Please see the screenshot of my database here

Thank you for your attention and time.

Here is my user_model.dart

class NayyaaUser {
  String? uid;
  String name;
  String email;
  String? phone;

  NayyaaUser({this.uid, required this.name, required this.email, this.phone});

  //send data to Firestore
  Map<String, dynamic> toMap() {
    return {
      'userId': uid,
      'userName': name,
      'userEmail': email,
      'userPhone': phone,
    };
  }

  //draw data from firestore
  factory NayyaaUser.fromFirestore(Map<String, dynamic> firestore) =>
      NayyaaUser(
        uid: firestore['userId'],
        email: firestore['userEmail'] ?? " ",
        name: firestore['userName'] ?? " ",
        phone: firestore['userPhone'] ?? " ",
      );
} 

Here is my user_provider.dart

class UserProvider extends ChangeNotifier {
  final firestoreService = FirestoreService();
  final authService = AuthService();


  String? _userId;
  String? _name;
  String? _email;
  String? _phone;


  //getters
  String? get userId => _userId;
  String? get name => _name;
  String? get email => _email;
  String? get phone => _phone;

  //setters
  changeName(String value) {
    _name = value;
    notifyListeners();
  }

  changeEmail(String value) {
    _email = value;
    notifyListeners();
  }

  changePhone(String value) {
    _phone = value;
    notifyListeners();
  }

  saveUserProfile() {
    if (_userId == null) {
      var updateUserProfile = NayyaaUser(
          // userId: _userId,
          uid: _userId,
          name: name ?? '',
          email: email ?? '',
          phone: phone ?? '');
      firestoreService.saveUserDataToFirestore(updateUserProfile);
    } else {
      var newUserProfile = NayyaaUser(
          // userId: _userId,
          uid: _userId,
          name: name ?? '',
          email: email ?? '',
          phone: phone ?? '');
      firestoreService.saveUserDataToFirestore(newUserProfile);
    }
  }
}

Here is auth_service.dart

class AuthService {
  final FirebaseAuth _authInstance = FirebaseAuth.instance;
//create user obj based on "User" from Firebase
  NayyaaUser? _userFromFirebase(User? user) {
    return user != null
        ? NayyaaUser(
            uid: user.uid,
            name: '',
            email: '',
            phone: '',
          )
        : null;
  }

// auth change user stream
  Stream<NayyaaUser?> get userAuthStatus {
    return _authInstance.authStateChanges().map(_userFromFirebase);
  }


// sign in with email + password
  Future signIn(String email, String password) async {
    try {
      UserCredential userAuthResult = await _authInstance
          .signInWithEmailAndPassword(email: email, password: password);
      User? user = userAuthResult.user;
      return _userFromFirebase(user!);
    } catch (e) {
      // ignore: avoid_print
      print(e.toString());
      return null;
    }
  }


  Future signUp(String email, String password) async {
    try {
      UserCredential userAuthResult = await _authInstance
          .createUserWithEmailAndPassword(email: email, password: password);
      User? user = userAuthResult.user;
      return _userFromFirebase(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

// sign out
  Future signOut() async {
    try {
      return await _authInstance.signOut();
    } catch (e) {
      // ignore: avoid_print
      print(e.toString());
      return null;
    }
  }
}

Here is firestore_service.dart

class FirestoreService {
  final CollectionReference _userRef =
      FirebaseFirestore.instance.collection('users');

  final CollectionReference _propertyRef =
      FirebaseFirestore.instance.collection('properties');


//add or update user to firestore
  Future<void> saveUserDataToFirestore(NayyaaUser nayyaaUserData) {
    return _userRef.doc(nayyaaUserData.uid).set(nayyaaUserData.toMap());
  }

  // fetch user data from firestore
  Stream<List<NayyaaUser>> getNayyaaUser() {
    return _userRef.snapshots().map((snapshot) => snapshot.docs
        .map((document) =>
            NayyaaUser.fromFirestore(document.data() as Map<String, dynamic>))
        .toList());
  }
}

Answer

Question answered by mavien (source).

After login/signup successfully you can get user id from FirebaseAuth.instance.currentUser?.uid

FIREBASE FLUTTER GOOGLE-CLOUD-FIRESTORE
SHARE: