I don't know where this error is coming from enter image description here
the debug console says the error is in the returning line and the return line return just returning a widget but the error is about string is null i don't from where this error is coming
this is notes_view.dart file
class NotesView extends StatefulWidget {
const NotesView({super.key});
@override
State<NotesView> createState() => _NotesViewState();
}
class _NotesViewState extends State<NotesView> {
late final FirebaseCloudStorage _notesService;
String get userId => AuthService.firebase().currentUser!.id;
@override
void initState() {
_notesService = FirebaseCloudStorage();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue[100],
appBar: AppBar(
title: const Text("Your Notes"),
actions: [
IconButton(
onPressed: () {
Navigator.of(context).pushNamed(createOrUpdateNoteRoute);
},
icon: const Icon(Icons.add),
),
PopupMenuButton<MenuActions>(
onSelected: (value) async {
switch (value) {
case MenuActions.logout:
final shouldLogout = await showLogoutDialog(context);
if (shouldLogout) {
await AuthService.firebase().logOut();
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (_) => false);
}
break;
}
},
itemBuilder: (context) {
return const [
PopupMenuItem<MenuActions>(
value: MenuActions.logout, child: Text("Log out")),
];
},
)
],
),
body: StreamBuilder(
stream: _notesService.allNotes(ownerUserId: userId),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.active:
if (snapshot.hasData) {
final allNotes = snapshot.data as Iterable<CloudNote>;
return NotesListView(
notes: allNotes,
onDeleteNote: (note) async {
await _notesService.deleteNote(
documentId: note.documentId);
print(note.documentId);
},
onTap: (note) {
Navigator.of(context).pushNamed(
createOrUpdateNoteRoute,
arguments: note,
);
},
);
} else {
return const CircularProgressIndicator();
}
default:
return const CircularProgressIndicator();
}
},
));
}
}
this is notes_list_view.dart file
typedef NoteCallback = void Function(CloudNote note);
class NotesListView extends StatelessWidget {
final Iterable<CloudNote> notes;
final NoteCallback onDeleteNote;
final NoteCallback onTap;
const NotesListView({
Key? key,
required this.notes,
required this.onDeleteNote,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: notes.length,
itemBuilder: (context, index) {
final note = notes.elementAt(index);
return ListTile(
onTap: () {
onTap(note);
},
textColor: Colors.black87,
title: Text(
note.text,
maxLines: 1,
softWrap: true,
overflow: TextOverflow.ellipsis,
),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red[200],
),
onPressed: () async {
final shouldDelete = await deleteDialog(context);
if (shouldDelete) {
onDeleteNote(note);
}
},
),
);
},
);
}
}
this is the firebase_cloud_storage.dart file
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:mynotes/services/cloud/cloud_note.dart';
import 'package:mynotes/services/cloud/cloud_storage_constants.dart';
import 'package:mynotes/services/cloud/cloud_storage_exceptions.dart';
class FirebaseCloudStorage {
final notes = FirebaseFirestore.instance.collection('notes');
Future<void> deleteNote({required String documentId}) async {
try {
await notes.doc(documentId).delete();
} catch (e) {
throw CouldNotDeleteNoteException();
}
}
Future<void> updateNote({
required String documentId,
required String text,
}) async {
try {
await notes.doc(documentId).update({textFieldName: text});
} catch (_) {
throw CouldNotUpdateNotesException();
}
}
Stream<Iterable<CloudNote>> allNotes({required String ownerUserId}) {
return notes.snapshots().map((event) => event.docs
.map((doc) => CloudNote.fromSnapshot(doc))
.where((note) => note.ownerUserId == ownerUserId));
}
Future<Iterable<CloudNote>> getNotes({required String ownerUserId}) async {
try {
return await notes
.where(ownerUserIdFieldName, isEqualTo: ownerUserId)
.get()
.then(
(value) => value.docs.map((doc) => CloudNote.fromSnapshot(doc)),
);
} catch (e) {
throw CouldNotGetAllNotesException();
}
}
Future<CloudNote> createNewNote({required String ownerUserId}) async {
final document = await notes.add({
ownerUserIdFieldName: ownerUserId,
textFieldName: '',
});
final fetchedNote = await document.get();
return CloudNote(
documentId: fetchedNote.id,
ownerUserId: ownerUserId,
text: '',
);
}
static final FirebaseCloudStorage _shared =
FirebaseCloudStorage._sharedInstance();
FirebaseCloudStorage._sharedInstance();
factory FirebaseCloudStorage() => _shared;
}
@immutable
class CloudNote {
final String documentId;
final String ownerUserId;
final String text;
const CloudNote({
required this.documentId,
required this.ownerUserId,
required this.text,
});
CloudNote.fromSnapshot(QueryDocumentSnapshot<Map<String, dynamic>> snapshot)
: documentId = snapshot.id,
ownerUserId = snapshot.data()[ownerUserIdFieldName],
text = snapshot.data()[textFieldName] as String;
}