Make a stream wait for data to assign a late property - flutter

I have following code.
I need to assign a late userName (not stored in database BID table) from the Bid Object that i retreive from the firestore with a stream.
The userName can be found in another table in the database (USER table).
I need to connect those 2 all while a streambuilder is building with BID object stream coming in.
Repository
final _firestoreDB = FirebaseFirestore.instance;
Future<String> getDbUserNameFromDbUserID({required String dbUserID}) async {
try {
final docUser = _firestoreDB.collection('users').doc(dbUserID);
final snapshot = await docUser.get();
if (snapshot.exists) {
if (snapshot.data() != null){
return DbUser.fromJson(snapshot.data()!).userName;
}
}
throw Exception("getDBUserByDBUserId() No fireStore userName found");
} catch (e) {
throw Exception(e);
}
}
Stream<List<Bid>> getAllBidsByItemId({required String itemID}) {
try {
return _firestoreDB
.collection('bids')/*.orderBy('timestamp')*/
.where('itemID', isEqualTo: itemID)
.snapshots()
.map((snapshot) =>
snapshot.docs.map((doc) {
Bid bid = Bid.fromJson(doc.data());
bid.bidId = doc.id;
**bid.userName = await getDbUserNameFromDbUserID( dbUserID: bid.bidderID); ///????**
return bid;
}).toList());
} catch (e) {
throw Exception(e);
}
}
model
class Bid {
late String bidId;
**late String userName;**
final String bidderID;
final String itemID;
final double price;
final DateTime timestamp;
Bid(
{
required this.bidderID,
required this.itemID,
required this.price,
required this.timestamp});
Map<String, dynamic> toJson() => {
'bidderID': bidderID,
'itemID': itemID,
'price': price,
'timestamp': timestamp,
};
static Bid fromJson(Map<String, dynamic> json) => Bid(
bidderID: json['bidderID'],
itemID: json['itemID'],
price: json['price'],
timestamp: (json['timestamp'] as Timestamp).toDate(),
);
}
How can I assign the late String userName when the stream gets the objects from the firestore?
Whats the best practice to do this? I assume this is not the best way to go about it?
I am using Bloc and Firestore Firebase
Thank you
SOLUTION
Stream<List<Bid>> getAllBidsByItemId({required String itemID}) async* {
try {
yield* _firestoreDB
.collection('bids')
.where('itemID', isEqualTo: itemID)
.snapshots()
.asyncMap<List<Bid>>((event) async {
List<Bid> bids = [];
for (var doc in event.docs) {
try {
Bid bid = Bid.fromJson(doc.data());
bid.bidId = doc.id;
bid.userName = await getDbUserNameFromDbUserID( dbUserID: bid.bidderID);
bids.add(bid);
} catch (e) {
throw Exception(e);
}
}
return bids;
});
} catch (e) {
throw Exception(e);
}
}
This worked for me

SOLUTION
Stream<List<Bid>> getAllBidsByItemId({required String itemID}) async* {
try {
yield* _firestoreDB
.collection('bids')
.where('itemID', isEqualTo: itemID)
.snapshots()
.asyncMap<List<Bid>>((event) async {
List<Bid> bids = [];
for (var doc in event.docs) {
try {
Bid bid = Bid.fromJson(doc.data());
bid.bidId = doc.id;
bid.userName = await getDbUserNameFromDbUserID( dbUserID: bid.bidderID);
bids.add(bid);
} catch (e) {
throw Exception(e);
}
}
return bids;
});
} catch (e) {
throw Exception(e);
}}

Related

My DocumentSnapshot type variable remains null despite the fact that I passed it to my function

I use flutter to retrieve a document from my firestore database. to do this, I create a DocumentSnapshot type variable which will be passed as a parameter to my getClasseName() function to retrieve the documents. Inside my function the document exists, so I assign it to my variable but my variable remains null when I want to use it
this is a snippet of my code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:ude/model/enseignant.dart';
class DBServices {
static final CollectionReference lyceecol =
FirebaseFirestore.instance.collection('Lycee');
static Future getUser(String? lycee, String? id) async {
try {
final QuerySnapshot<Object?> snapshot = await lyceecol
.doc(lycee)
.collection('Enseignant')
.where('Id', isEqualTo: id)
.get();
final EnseignantM userData = snapshot.docs
.map((QueryDocumentSnapshot<Object?> e) => EnseignantM.fromSnapshot(
e as DocumentSnapshot<Map<String?, dynamic>>))
.single;
return userData;
} catch (e) {
print('ENSEIGNANT NOT FOUND');
print(e);
throw e;
}
}
static Future getClasseName(
String? lycee, String? id, List<String> list) async {
try {
String classeName;
int i = 0;
final snapshot = await lyceecol
.doc(lycee)
.collection('Enseignant')
.doc(id)
.collection('Classes')
.get();
for (var classe in snapshot.docs) {
DocumentReference<Map<String, dynamic>> classeRef =
classe.data()["reference"];
DocumentSnapshot<Map<String, dynamic>>? classRoom;
await DBServices.getClasse(classeRef.path, classRoom);
if (classRoom != null) {
print('CLASSENAME ${classRoom.data()!["Nom"]}');
classeName = classRoom.data()!["Nom"];
list[i] = classeName;
print(list[i]);
i++;
} else {
print('Impossible de charger les classes affilees a cet enseignant');
}
}
} catch (e) {
print(e);
rethrow;
}
}
static Future<void> getClasse(
String? path, DocumentSnapshot<Map<String, dynamic>>? classroom) async {
try {
await FirebaseFirestore.instance.doc(path!).get().then((snapshot) {
if (snapshot.exists) {
classroom = snapshot; //.data()!["Nom"];
} else {
debugPrint("Document not found");
}
});
debugPrint('CLASSROOMMMM: ${classroom!.data()!["Nom"]}');
} catch (e) {
debugPrint('CLASSE Not EXIST');
print(e);
rethrow;
}
}
}
---
/*this is where the problem is*/
static Future getClasseName(
String? lycee, String? id, List<String> list) async {
try {
String classeName;
int i = 0;
final snapshot = await lyceecol
.doc(lycee)
.collection('Enseignant')
.doc(id)
.collection('Classes')
.get();
for (var classe in snapshot.docs) {
DocumentReference<Map<String, dynamic>> classeRef =
classe.data()["reference"];
DocumentSnapshot<Map<String, dynamic>>? classRoom;
await DBServices.getClasse(classeRef.path, classRoom);
if (classRoom != null) {
print('CLASSENAME ${classRoom.data()!["Nom"]}');
classeName = classRoom.data()!["Nom"];
list[i] = classeName;
print(list[i]);
i++;
} else {
print('Impossible de charger les classes affilees a cet enseignant');
}
}
} catch (e) {
print(e);
rethrow;
}
}
static Future<void> getClasse(
String? path, DocumentSnapshot<Map<String, dynamic>>? classroom) async {
try {
await FirebaseFirestore.instance.doc(path!).get().then((snapshot) {
if (snapshot.exists) {
classroom = snapshot; //.data()!["Nom"];
} else {
debugPrint("Document not found");
}
});
debugPrint('CLASSROOMMMM: ${classroom!.data()!["Nom"]}');
} catch (e) {
debugPrint('CLASSE Not EXIST');
print(e);
rethrow;
}
}
I tried not to pass my variable as a parameter and to directly assign the Document returned by the function to it, but it didn't work.
Your help will be invaluable to me

type 'Null' is not a subtype of type 'DatabaseNotes' in type cast

The problem lies in the FutureBuilder widget section. I am trying to get the data from a snapshot in a FutureBuilder, but I get an error as 'type 'Null' is not a subtype of type 'DatabaseNotes' in type cast'. I tried declaring the _note field as late final but it still throws the same error. I have taken care of the null safety part by adding the ? in after the data type (here, it is DatabaseNotes). I still don't get what is wrong here.
The following is the code for the NewNoteView widget:
class NewNoteView extends StatefulWidget {
const NewNoteView({Key? key}) : super(key: key);
#override
State<NewNoteView> createState() => _NewNoteViewState();
}
class _NewNoteViewState extends State<NewNoteView> {
DatabaseNotes? _note;
late final NotesService _notesService;
late final TextEditingController _textController;
#override
void initState() {
_notesService = NotesService();
_textController = TextEditingController();
super.initState();
}
void _textControllerListener() async {
final note = _note;
if (note == null) {
return;
}
final text = _textController.text;
await _notesService.updateNote(
note: note,
text: text,
);
}
void _setupTextControllerListener() {
_textController.removeListener(_textControllerListener);
_textController.addListener(_textControllerListener);
}
Future<DatabaseNotes> createNewNote() async {
final existingNote = _note;
if (existingNote != null) {
return existingNote;
}
final currentUser = AuthService.firebase().currentUser!;
final email = currentUser.email!;
final owner = await _notesService.getUser(email: email);
return await _notesService.createNote(owner: owner);
}
void _deleteNoteIfTextIsEmpty() {
final note = _note;
if (_textController.text.isEmpty && note != null) {
_notesService.deleteNote(id: note.id);
}
}
void _saveNoteIfTextNotEmpty() async {
final note = _note;
final text = _textController.text;
if (note != null && text.isNotEmpty) {
await _notesService.updateNote(
note: note,
text: text,
);
}
}
#override
void dispose() {
_deleteNoteIfTextIsEmpty();
_saveNoteIfTextNotEmpty();
_textController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('New note'),
),
body: FutureBuilder(
future: createNewNote(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
_note = snapshot.data as DatabaseNotes;
_setupTextControllerListener();
return TextField(
controller: _textController,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: const InputDecoration(
hintText: 'Start typing your note...',
),
);
default:
return const CircularProgressIndicator();
}
},
));
}
}
The following is the code for NotesService:
class DatabaseAlreadyOpenException implements Exception {}
class NotesService {
Database? _db;
List<DatabaseNotes> _notes = [];
static final NotesService _shared = NotesService._sharedInstance();
NotesService._sharedInstance();
factory NotesService() => _shared;
final _notesStreamController =
StreamController<List<DatabaseNotes>>.broadcast();
Stream<List<DatabaseNotes>> get allNotes => _notesStreamController.stream;
Future<DatabaseUser> getOrCreateUser({required String email}) async {
try {
final user = getUser(email: email);
return user;
} on CouldNotFindUser {
final createdUser = createUser(email: email);
return createdUser;
} catch (e) {
rethrow;
}
}
Future<void> _cacheNotes() async {
final allNotes = await getAllNotes();
_notes = allNotes.toList();
_notesStreamController.add(_notes);
}
Future<DatabaseNotes> updateNote({
required DatabaseNotes note,
required String text,
}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
// make sure note exists
await getNote(id: note.id);
// update DB
final updatesCount = await db.update(notesTable, {
textColumn: text,
isSyncedWithCloudColumn: 0,
});
if (updatesCount == 0) {
throw CouldNotUpdateNote();
} else {
final updatedNote = await getNote(id: note.id);
_notes.removeWhere((note) => note.id == updatedNote.id);
_notes.add(updatedNote);
_notesStreamController.add(_notes);
return updatedNote;
}
}
Future<Iterable<DatabaseNotes>> getAllNotes() async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final notes = await db.query(
notesTable,
);
return notes.map((noteRow) => DatabaseNotes.fromRow(noteRow));
}
Future<DatabaseNotes> getNote({required int id}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final notes = await db.query(
notesTable,
limit: 1,
where: 'id = ?',
whereArgs: [id],
);
if (notes.isEmpty) {
throw CouldNotFindNote();
} else {
final note = DatabaseNotes.fromRow(notes.first);
_notes.removeWhere((note) => note.id == id);
_notes.add(note);
_notesStreamController.add(_notes);
return note;
}
}
Future<int> deleteAllNotes() async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final numberOfDeletions = await db.delete(notesTable);
_notes = [];
_notesStreamController.add(_notes);
return numberOfDeletions;
}
Future<void> deleteNote({required int id}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final deletedCount = await db.delete(
notesTable,
where: 'id = ?',
whereArgs: [id],
);
if (deletedCount == 0) {
throw CouldNotDeleteNote();
} else {
_notes.removeWhere((note) => note.id == id);
_notesStreamController.add(_notes);
}
}
Future<DatabaseNotes> createNote({required DatabaseUser owner}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
// make sure the owner exists in the database with the correct id
final dbUser = await getUser(email: owner.email);
if (dbUser != owner) {
throw CouldNotFindUser();
}
const text = '';
// create the note
final noteId = await db.insert(notesTable, {
userIdColumn: owner.id,
textColumn: text,
isSyncedWithCloudColumn: 1,
});
final note = DatabaseNotes(
id: noteId,
userId: owner.id,
text: text,
isSyncedWithCloud: true,
);
_notes.add(note);
_notesStreamController.add(_notes);
return note;
}
Future<DatabaseUser> getUser({required String email}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final results = await db.query(
userTable,
limit: 1,
where: 'email = ?',
whereArgs: [email.toLowerCase()],
);
if (results.isEmpty) {
throw CouldNotFindUser();
} else {
return DatabaseUser.fromRow(results.first);
}
}
Future<DatabaseUser> createUser({required String email}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final results = await db.query(
userTable,
limit: 1,
where: 'email = ?',
whereArgs: [email.toLowerCase()],
);
if (results.isNotEmpty) {
throw UserAlreadyExists();
}
final userId = await db.insert(userTable, {
emailColumn: email.toLowerCase(),
});
return DatabaseUser(
id: userId,
email: email,
);
}
Future<void> deleteUser({required String email}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final deletedCount = await db.delete(
userTable,
where: 'email = ?',
whereArgs: [email.toLowerCase()],
);
if (deletedCount != 1) {
throw CouldNotDeleteUser();
}
}
Database _getDatabaseOrThrow() {
final db = _db;
if (db == null) {
throw DatabaseIsNotOpen();
} else {
return db;
}
}
Future<void> close() async {
final db = _db;
if (db == null) {
throw DatabaseIsNotOpen();
} else {
await db.close();
_db = null;
}
}
Future<void> _ensureDbIsOpen() async {
try {
await open();
} on DatabaseAlreadyOpenException {
//empty block
}
}
Future<void> open() async {
if (_db != null) {
throw DatabaseAlreadyOpenException;
}
try {
final docsPath = await getApplicationDocumentsDirectory();
final dbPath = join(docsPath.path, dbName);
final db = await openDatabase(dbPath);
_db = db;
// create the user table
await db.execute(createUserTable);
// create the notes table
await db.execute(createNotesTable);
await _cacheNotes();
} on MissingPlatformDirectoryException {
throw UnableToGetDocumentsDirectory;
}
}
}
#immutable
class DatabaseUser {
final int id;
final String email;
const DatabaseUser({
required this.id,
required this.email,
});
DatabaseUser.fromRow(Map<String, Object?> map)
: id = map[idColumn] as int,
email = map[emailColumn] as String;
#override
String toString() => 'Person id = $id, email = $email';
#override
bool operator ==(covariant DatabaseUser other) => id == other.id;
#override
int get hashCode => id.hashCode;
}
class DatabaseNotes {
final int id;
final int userId;
final String text;
final bool isSyncedWithCloud;
DatabaseNotes({
required this.id,
required this.userId,
required this.text,
required this.isSyncedWithCloud,
});
DatabaseNotes.fromRow(Map<String, Object?> map)
: id = map[idColumn] as int,
userId = map[userIdColumn] as int,
text = map[textColumn] as String,
isSyncedWithCloud = (map[isSyncedWithCloudColumn]) == 1 ? true : false;
#override
String toString() =>
'Note, ID = $id, userId = $userId, isSyncedWithCloud = $isSyncedWithCloud, text = $text';
#override
bool operator ==(covariant DatabaseNotes other) => id == other.id;
#override
int get hashCode => id.hashCode;
}
You can place the '?' after DatabaseNotes (or DatabaseNote if you are following the FreeCodeCamp tutorial more precisely). Your IDE will probably then tell you the cast to DatabaseNotes is unnecessary. I then removed the 'as DatabaseNotes' entirely and it worked. Final line of code as below.
_note = snapshot.data;
Try this
FutureBuilder<DatabaseNotes>(your code);
I found the mistake and turns out I wasn't handling the null safety after all; I feel like an idiot.
I created an instance of 'DatabaseNotes?' _note, but when I assigned the snapshot's data inside the FutureBuilder in the line _note = snapshot.data as DatabaseNotes, I forgot to add the ? after DatabaseNotes.
The statement should be: _note = snapshot.data as DatabaseNotes?;
Thank you everyone for your answers and suggestions. I highly appreciate your efforts.
After
_note = snapshot.data as DatabaseNotes;
just put
?
This null safety sign. And your code will run errorless. My code so suffers for this damn sign.

Null is not a subtype of type String

Hello I’m new to flutter
I’m trying to retrieve the user data from his email but i got this error [Null is not a subtype of type String]
The data I’m trying to retrieve is not null
This is my code
class _ProfilePageState extends State<ProfilePage> {
late User user;
final _auth = FirebaseAuth.instance;
late User signedInUser;
var id;
var email;
var name;
var age;
var sex;
#override
void initState() {
super.initState();
onRefresh(FirebaseAuth.instance.currentUser);
getCurrentUser();
}
onRefresh(userCare)
{
setState(()
{
user = userCare;
});
}
void getCurrentUser()
{
try {
final user = _auth.currentUser;
if (user != null) {
signedInUser = user;
email = signedInUser.email;
id = signedInUser.uid;
}
} catch (e) {
print(e);
}
}
void getData() {
FirebaseFirestore.instance
.collection('users')
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
if (doc["email"] == signedInUser.email) {
name = doc['name'];
age = doc['age'];
sex = doc['sex'];
print(doc['name']);
}
});
});
}
This is my data
I want to retrieve then but i can’t because it says null how to fix the error?
this is the data I’m trying to retrieve
the error image
Please try this Code:
void getData() async {
await FirebaseFirestore.instance
.collection('users')
.get()
.then((value) {
for(var doc in value.docs) {
if (doc["email"] == signedInUser.email) {
name = doc.data()['name'];
age = doc.data()['age'];
sex = doc.data()['sex'];
print(doc.data()['name']);
}
}
});
}

Flutter Future<Object> not return

Becoming mad about a simple piece of code...
I have a class:
class Monkey {
final String uid;
final String email;
final String password;
final int registrationMethod;
final int accountCreationTime; //* in milliseconds
final String name;
final String nickname;
final int birthday; //* in milliseconds
final String phone;
final String countryCode;
final String codiceComune;
final String comune;
final String provincia;
final String regione;
final String cap;
final String sigla;
final String zona;
final String codiceCatastale;
final int popolazione;
final bool isRegistered;
final bool shareName;
final bool acceptedRules;
final String picUrl;
final int
userPicType; //* 1 - Email / 2 - Google / 3 - Facebook / 4 - Apple / 5 - File
const Monkey(
this.uid,
this.email,
this.password,
this.registrationMethod,
this.accountCreationTime,
this.name,
this.nickname,
this.birthday,
this.phone,
this.countryCode,
this.codiceComune,
this.comune,
this.provincia,
this.regione,
this.cap,
this.sigla,
this.zona,
this.codiceCatastale,
this.popolazione,
this.isRegistered,
this.shareName,
this.acceptedRules,
this.picUrl,
this.userPicType,
);
}
I have a variable:
static Monkey monkey = const Monkey(
'uid',
'email',
'password',
0,
0,
'name',
'nickname',
0,
'phone',
'countryCode',
'codiceComune',
'comune',
'provincia',
'regione',
'cap',
'sigla',
'zona',
'codiceCatastale',
0,
false,
false,
false,
'picUrl',
0);
I have a method to fill the variable:
Future<Monkey?> getMonkey() async {
try {
await _firestore
.collection('users')
.doc(getUID())
.get()
.then((DocumentSnapshot documentSnapshot) {
Map<String, dynamic> data =
documentSnapshot.data() as Map<String, dynamic>;
if (data.isNotEmpty) {
if (kDebugMode) {
print("Point 1");
}
return Monkey(
data['uid'],
data['email'],
data['password'],
data['registrationMethod'],
data['accountCreationTime'],
data['name'],
data['nickname'],
data['birthday'],
data['phone'],
data['countryCode'],
data['codiceComune'],
data['comune'],
data['provincia'],
data['regione'],
data['cap'],
data['sigla'],
data['zona'],
data['codiceCatastale'],
data['popolazione'],
data['isRegistered'],
data['shareName'],
data['acceptedRules'],
data['picUrl'],
data['userPicType']);
} else {
if (kDebugMode) {
print(
"La lettura di monkey non ha restituito dati, elsedella lettura Monkey.");
}
return null;
}
});
} catch (err) {
if (kDebugMode) {
print("Errore durante la lettura di Monke: " + err.toString());
}
return null;
}
if (kDebugMode) {
print(
"Point 2");
}
return null;
}
This is my execution:
Variables.monkey = (await _firebase.getMonkey())!;
As I can see my code fire Print Point 1 but also Print Point 2.
I printed data and it is filled successfully.
But I receive this error:
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: Null check operator used on a null value
#0 _RegistrationScreenState.registerUser
package:whybye/screens/registration_screen.dart:345
edit:
Just removed any 'final' from Class Monkey, however same result.
The error is here:
Future<Monkey?> getMonkey() async {
try {
await _firestore
.collection('users')
.doc(getUID())
.get()
.then((DocumentSnapshot documentSnapshot) {
Map<String, dynamic> data =
documentSnapshot.data() as Map<String, dynamic>;
if (data.isNotEmpty) {
if (kDebugMode) {
print("Point 1");
}
return Monkey(
data['uid'],
data['email'],
data['password'],
data['registrationMethod'],
data['accountCreationTime'],
data['name'],
data['nickname'],
data['birthday'],
data['phone'],
data['countryCode'],
data['codiceComune'],
data['comune'],
data['provincia'],
data['regione'],
data['cap'],
data['sigla'],
data['zona'],
data['codiceCatastale'],
data['popolazione'],
data['isRegistered'],
data['shareName'],
data['acceptedRules'],
data['picUrl'],
data['userPicType']);
} else {
if (kDebugMode) {
print(
"La lettura di monkey non ha restituito dati, elsedella lettura Monkey.");
}
return null;
}
});
} catch (err) {
if (kDebugMode) {
print("Errore durante la lettura di Monke: " + err.toString());
}
return null;
}
if (kDebugMode) {
print(
"Point 2");
}
return null;
}
Where return Monkey is inside another process (await _firestore).
This mean the code is ok but I had to add:
Monkey monkey;
monkey = await _firestore...
return monkey(...)...
and outside the _firestore process return the real monkey...
Before I found the solution I tried tons of code and finally I switched to String:
Future<String> getMonkey() async {
String res;
try {
res = await _firestore
.collection('users')
.doc(getUID())
.get()
.then((DocumentSnapshot documentSnapshot) {
Map<String, dynamic> data =
documentSnapshot.data() as Map<String, dynamic>;
if (data.isNotEmpty) {
if (kDebugMode) {
print("I dati di Monkey non sono vuoti: ");
}
Monkey.uid = data['uid'];
Monkey.email = data['email'];
Monkey.password = data['password'];
Monkey.registrationMethod = data['registrationMethod'];
Monkey.accountCreationTime = data['accountCreationTime'];
Monkey.name = data['name'];
Monkey.nickname = data['nickname'];
Monkey.birthday = data['birthday'];
Monkey.phone = data['phone'];
Monkey.countryCode = data['countryCode'];
Monkey.codiceComune = data['codiceComune'];
Monkey.comune = data['comune'];
Monkey.provincia = data['provincia'];
Monkey.regione = data['regione'];
Monkey.cap = data['cap'];
Monkey.sigla = data['sigla'];
Monkey.zona = data['zona'];
Monkey.codiceCatastale = data['codiceCatastale'];
Monkey.popolazione = data['popolazione'];
Monkey.isRegistered = data['isRegistered'];
Monkey.shareName = data['shareName'];
Monkey.acceptedRules = data['acceptedRules'];
Monkey.picUrl = data['picUrl'];
Monkey.userPicType = data['userPicType'];
return 'success';
} else {
if (kDebugMode) {
print(
"La lettura di monkey non ha restituito dati, elsedella lettura Monkey.");
}
return 'error';
}
});
} catch (err) {
if (kDebugMode) {
print("Errore durante la lettura di Monkey: " + err.toString());
}
return 'error';
}
if (res == 'success') {
return 'success';
} else {
return 'error';
}
}
As you can see the real Return function is at bottom:
if (res == 'success') {
return 'success';
} else {
return 'error';
}
This error occurs when you use a bang operator (!) on a nullable instance which wasn't initialized.
Replace your execution with this:
var monkey = await _firebase.getMonkey();
if(monkey != null){
Variables.monkey = monkey;
}
I hope it would help you.

Flutter & Firebase - Get a specific field from document

I have been trying to get a specific field from a specific document. I need token for toWho. But I always got null. How do I fix this?
Main Code is
Future<String> getUserToken(String toWho) async {
DocumentSnapshot _doc = await FirebaseFirestore.instance.doc("tokens/" + toWho).get();
if (_doc != null) {
Map<String, dynamic> _data = _doc.data();
return _data["token"];
} else {
return null;
}
}
in Repository
Future<bool> sendMessage(
MessageModel sendingMessage, UserModel currentUser) async {
if (appMode == AppMode.DEBUG) {
return true;
} else {
var _writePrcs = await _firestoreDBService.saveMessage(sendingMessage);
if (_writePrcs) {
var _token = "";
if (_userToken.containsKey(sendingMessage.toWho)) {
_token = _userToken[sendingMessage.toWho];
print("Token lokalden geldi.");
} else {
_token = await _firestoreDBService.getUserToken(sendingMessage.toWho);
_userToken[sendingMessage.toWho] = _token;
print("Token veritabanından geldi.");
}
Thanks for your help from now on
Try ...........
Future<String> getUserToken(String toWho) async {
DocumentSnapshot _doc = await
FirebaseFirestore.instance.collection("tokens/groupChatId/message").doc(toWho).get();
if (_doc != null) {
Map<String, dynamic> _data = _doc.data();
return _data["token"];
} else {
return null;
}
}