Search code examples
firebaseflutterdartflutter-provider

Firebase, Flutter, Provider - Mapping, and Using Data via Provider


I'm new to flutter and firebase (and yes i know this question has been asked before). But i've seen plenty of different ways to map firebase data into provider, and some reason cannot get a single to work. I have this data structure. And all i wish, is to Map it into an class / object.

Firebase screenshot

This is my data model.dart:

@immutable
class Requests {
  Requests({
    this.name = '',
    this.pairingId = 0,
  });

  final String name;
  final double pairingId;

  Requests.fromJson(Map<String, Object?> json)
      : this(
          name: json['name']! as String,
          pairingId: json['pairingId'] as double,
        );

  Map<String, Object?> toJson() {
    return {
      'name': name,
      'pairingId': pairingId,
    };
  }
}

@immutable
class UserDataTest with ChangeNotifier {
  UserDataTest({
    this.firstName = '',
    this.lastName = '',
    this.gender = '',
    this.dateOfBirth,
    this.userUID = '',
    this.uidp = '',
    this.pairingId = 0,
    this.requests = const [],
  });

  UserDataTest.fromJson(Map<String, Object?> json)
      : this(
          firstName: json['firstName']! as String,
          lastName: json['lastName']! as String,
          gender: json['gender']! as dynamic,
          dateOfBirth: json['dateOfBirth']! as DateTime?,
          userUID: json['userUID']! as String,
          uidp: json['uidp']! as String,
          pairingId: json['pairingId']! as double,
          requests: json['requests']! as List<Requests>,
        );

  late final String firstName;
  final String lastName;
  final dynamic gender;
  final DateTime? dateOfBirth;
  final String userUID;
  final String uidp;
  final double pairingId;
  final List<Requests> requests;

  Map<String, Object?> toJson() {
    return {
      'firstName': firstName,
      'lastName': lastName,
      'gender': gender,
      'dateOfBirth': dateOfBirth,
      'userUID': userUID,
      'uidp': uidp,
      'pairingId': pairingId,
      'requests': requests,
    };
  }
}

But from here i dont have any solution that works just partly. Again, my wish is to be able to just write, ex. user.firstName and display the first Name. How do i get to there? I know im missing the call to firebase, but i haven't been successful in making one. I dont know if have to do something inside the provider. (Yes i have a multiprovider at the top of my tree and a call to the provider where im using it or wanting to)


Solution

  • My suggestion: start over. Just start by creating a simple class manually with just a few of the fields from Firebase, and work your way out. For example use the UserDataTest and just make it a class:

    class UserDataTest {
      String? firstName;
      String? lastName;
    
      UserDataTest({ this.firstName, this.lastName });
    
      factory UserDataTest.fromJson(Map<String, dynamic> json) {
       return UserDataTest(
         firstName: json['firstName'],
         lastName: json['lastName'],
       );
      }
    }
    

    Try to keep these classes as plain as possible. Create other classes for your services and then make those extend ChangeNotifier, like to encapsulate your business logic and trigger notifications.

    Then, from Firebase you will easily be able to do stuff like:

    List<UserDataTest> userData = [];
    FirebaseFirestore.instance.collection('userdata').get().then((QuerySnapshot snapshot) {
      userData = snapshot.docs.map((doc) => UserDataTest.fromJson(doc.data())).toList();
    });
    

    My two cents.