Reputation: 81
I am attempting to Deserialize data from Firestore Map into a new Class and call that Class using Provider. I have followed several tutorials (https://fireship.io/lessons/advanced-flutter-firebase/) with no success.
///auth_class.dart
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class UserCheck extends ChangeNotifier {
final _auth = FirebaseAuth.instance;
FirebaseUser loggedInUser;
var userDetails;
final String id;
String firstName;
final String lastName;
final String userEmail;
final String userOrg;
final Timestamp regDate;
final String date;
UserCheck({
this.id,
this.firstName,
this.lastName,
this.userEmail,
this.userOrg,
this.regDate,
this.date,
});
factory UserCheck.fromSnap(DocumentSnapshot ds) {
Map data = ds.data;
return UserCheck(
id: ds.documentID,
firstName: ds['fname'] ?? '',
lastName: data['lname'] ?? '',
userEmail: data['regEmail'] ?? '',
userOrg: data['org'] ?? '',
);
}
I then try to call using
//database_service.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:oast_app/widgets/auth_class.dart';
class DatabaseService {
Stream<List<UserCheck>> streamUser(FirebaseUser user){
var ref = Firestore.instance.collection('users').document('${user.uid}').snapshots();
return ref.map((list) => {
return list.data.map((ds) => UserCheck.fromSnap(ds)).toList()
});
}
}
Error Messages: < Compiler message: lib/widgets/database_service.dart:12:7: Error: Unexpected token 'return'. return list.data.map((ds) => UserCheck.fromSnap(ds)).toList() ^^^^^^ lib/widgets/database_service.dart:12:55: Error: The argument type 'String' can't be assigned to the parameter type 'DocumentSnapshot'. - 'DocumentSnapshot' is from 'package:cloud_firestore/cloud_firestore.dart' ('../../Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.12.11/lib/cloud_firestore.dart'). return list.data.map((ds) => UserCheck.fromSnap(ds)).toList() ^ lib/widgets/database_service.dart:12:46: Error: A value of type 'UserCheck' can't be assigned to a variable of type 'MapEntry'. - 'UserCheck' is from 'package:oast_app/widgets/auth_class.dart' ('lib/widgets/auth_class.dart'). - 'MapEntry' is from 'dart:core'. return list.data.map((ds) => UserCheck.fromSnap(ds)).toList() ^ lib/widgets/database_service.dart:12:28: Error: The argument type 'MapEntry Function(String)' can't be assigned to the parameter type 'MapEntry Function(String, dynamic)'. - 'MapEntry' is from 'dart:core'. return list.data.map((ds) => UserCheck.fromSnap(ds)).toList() ^ lib/widgets/database_service.dart:12:60: Error: The method 'toList' isn't defined for the class 'Map'. - 'Map' is from 'dart:core'. Try correcting the name to the name of an existing method, or defining a method named 'toList'. return list.data.map((ds) => UserCheck.fromSnap(ds)).toList() ^^^^^^ lib/widgets/database_service.dart:11:30: Error: A value of type 'Set' can't be assigned to a variable of type 'List'. - 'Set' is from 'dart:core'. - 'List' is from 'dart:core'. - 'UserCheck' is from 'package:oast_app/widgets/auth_class.dart' ('lib/widgets/auth_class.dart'). return ref.map((list) => { >
Upvotes: 2
Views: 4990
Reputation: 729
You can use asyncMap
Stream<FirestoreResponse> getStream(String collection) {
var snapshots =
FirebaseFirestore.instance.collection(collection).snapshots();
return snapshots.asyncMap((event) => FirestoreResponse(
event.docs, event.docChanges, event.metadata, event.size));
}
Using a model like this
class FirestoreResponse extends Equatable {
/// Gets a list of all the documents included in this snapshot.
final List<QueryDocumentSnapshot<Map<String, dynamic>>> docs;
/// An array of the documents that changed since the last snapshot. If this
/// is the first snapshot, all documents will be in the list as Added changes.
final List<DocumentChange<Map<String, dynamic>>> docChanges;
/// Returns the [SnapshotMetadata] for this snapshot.
final SnapshotMetadata metadata;
/// Returns the size (number of documents) of this snapshot.
final int size;
/// Constructor
const FirestoreResponse(this.docs, this.docChanges, this.metadata, this.size);
@override
List<Object?> get props => [
docs,
docChanges,
metadata,
size,
];
}
Upvotes: 0
Reputation: 1962
Instead of using .data;
you need to use .data();
to actually get the document data.
However you can directly get each value of the Firestore map by using .data().map['[FIELD_NAME]']
Also the part of firstName should be data['fname'] as already stated.
Upvotes: 1
Reputation: 41
Just a guess, shouldn't your following code;
firstName: ds['fname'] ?? '',
be
firstName: data['fname'] ?? '',
instead?
Upvotes: 0