The method 'data' was called on null. Receiver: null Tried calling: data() in flutter firebase chat app - flutter

The following NoSuchMethodError was thrown building FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(dirty, state: _FutureBuilderState<DocumentSnapshot<Map<String, dynamic>>>#c2b0e):
The method 'data' was called on null.
Receiver: null
Tried calling: data()
in chatApp :-
here source code highlighted
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:jobkar/public/model/user_model.dart';
import 'package:jobkar/public/view/navigation/message/chat_room.dart';
class Message extends StatefulWidget {
const Message({Key? key}) : super(key: key);
#override
State<Message> createState() => _MessageState();
}
class _MessageState extends State<Message> {
final currentUser = FirebaseAuth.instance.currentUser;
final searchController = TextEditingController();
String search = '';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 50,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.white),
child: Row(
children: [
Flexible(
child: TextFormField(
controller: searchController,
onChanged: (value) {
search = value;
},
decoration: InputDecoration(
hintText: 'Search person',
border: InputBorder.none,
prefixIcon: const Icon(
Icons.dehaze,
size: 26,
color: Colors.black54,
),
hintStyle: GoogleFonts.raleway(
fontSize: 16, fontWeight: FontWeight.normal)),
),
),
Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.black54),
child: Center(
child: IconButton(
onPressed: () {
setState(() {});
},
icon: const Icon(
Icons.search,
color: Colors.white,
),
),
),
),
),
],
),
),
),
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('users')
.doc(currentUser!.uid)
.collection('message')
.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(
color: Colors.blue[900],
),
);
} else if (snapshot.hasError) {
return const Center(
child: Text("Something went wrong please try later"),
);
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
var friendId = snapshot.data!.docs[index].id;
var lastMessage = snapshot.data!.docs[index]['lastMessage'];
return FutureBuilder(
future: FirebaseFirestore.instance.collection('users').doc(friendId).get(),
builder: (BuildContext context , AsyncSnapshot snapshot) {
**final userModel = UserModel.fromMap(snapshot.data.data() as Map<String,dynamic>);**
if (snapshot.hasData) {
var friend = snapshot.data;
if (search.isEmpty) {
return ListTile(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) =>
ChatRoom(
userModel: userModel,
friendName: friend['name'],
friendImage: friend['imageUrl'],
friendId: friend['uid'],
friendEmail: friend['email']
),
),
);
},
title: Text(
friend['name'],
style: GoogleFonts.raleway(
fontWeight: FontWeight.normal),
),
subtitle: Text(lastMessage,
overflow: TextOverflow.ellipsis,
style: GoogleFonts.raleway(
fontWeight: FontWeight.normal),
),
leading: Container(
height: 45,
width: 45,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.white),
child: const Center(
child: Icon(Icons.person),
),
),
);
} else if (friend['name']
.toString()
.toLowerCase()
.startsWith(search.toLowerCase()) ||
friend['name']
.toString()
.toUpperCase()
.startsWith(search.toUpperCase())) {
return ListTile(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) =>
ChatRoom(
userModel: userModel,
friendName: friend['name'],
friendImage: friend['imageUrl'],
friendId: friend['uid'],
friendEmail: friend['email']
),
),
);
},
title: Text(
friend['name'],
style: GoogleFonts.raleway(
fontWeight: FontWeight.normal),
),
subtitle: Text(lastMessage,
style: GoogleFonts.raleway(
fontWeight: FontWeight.normal),
),
leading: Container(
height: 45,
width: 45,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.white),
child: const Center(
child: Icon(Icons.person),
),
),
);
}
return Container();
}
return Container();
}
);
});
}
return Container();
},
),
),
],
),
);
}
}

Generate the model after getting data like
builder: (BuildContext context , AsyncSnapshot snapshot) {
if (snapshot.hasData) {
final mapData = snapshot.data.data() as Map?;
if(mapData == null) return Text("Got null data");
final userModel = UserModel.fromMap(mapData);
var friend = snapshot.data;

Related

Flutter firebase chat problem in redirecting user chatroom

Hi guys i'm a begginer in flutter development , i am stuck in a problem,
problem is i want to redirect from selected (homepage.dart file) user in the list to chatroom where i can chat this user but i am not able to do, here is problem i'm facing: Anyone give me solution .
code:-
homepage.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:jobong/model/chatroom_model.dart';
import 'package:jobong/model/signup.dart';
import 'package:jobong/view/chatroom.dart';
class HomePage extends StatefulWidget {
final List<User>? users;
const HomePage({Key? key, this.users}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final auth = FirebaseAuth.instance;
final systemColor =
const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
final User? currentUser = FirebaseAuth.instance.currentUser;
final String uid = FirebaseAuth.instance.currentUser!.uid;
final searchController = TextEditingController();
String search = '';
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(systemColor);
return Scaffold(
backgroundColor: Colors.grey[300],
drawer: const Drawer(
child: DrawerPage(),
),
appBar: AppBar(
titleSpacing: 0,
backgroundColor: Colors.blue[900],
title: Text(
"ChatApp",
style: GoogleFonts.raleway(),
),
actions: [
IconButton(
onPressed: () async {
await FirebaseAuth.instance.signOut();
setState(() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SignUp()),
);
});
},
icon: const Icon(Icons.logout_outlined),
),
],
),
body: Column(
children: [
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.all(20.0),
child: TextFormField(
controller: searchController,
onChanged: (String value) {
search = value;
},
decoration: InputDecoration(
hintText: 'Search user',
prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
hintStyle: GoogleFonts.raleway(
fontSize: 16, fontWeight: FontWeight.normal),
),
),
),
ElevatedButton(
onPressed: () {
setState(() {});
},
child: Text(
"Search",
style: GoogleFonts.raleway(),
),
),
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream:
FirebaseFirestore.instance.collection('Users')
.where('uid',isNotEqualTo: currentUser!.uid).snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot snap = snapshot.data!.docs[index];
final chatRoomModel = ChatRoomModel(
friendName: currentUser!.displayName.toString(),
friendUid: currentUser!.uid,
friendEmail: currentUser!.email.toString(),
);
final targetUserName = chatRoomModel.friendName;
final targetUserEmail = chatRoomModel.friendEmail ;
final targetUserUid = chatRoomModel.friendUid;
if (search.isEmpty) {
return ListTile(
title: Text(snap['name']),
subtitle: Text(snap['email']),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ChatRoom(
friendName: snap['name'] ,
friendEmail: snap['email'],
friendUid: snap['uid'],
),
),
);
},
leading: Container(
height: 45,
width: 45,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white),
child: const Center(
child: Icon(Icons.person),
),
),
);
}
if (snap['name'].toString().toLowerCase().startsWith(search.toLowerCase()) ||
snap['name'].toString().toUpperCase().startsWith(search.toUpperCase())) {
return ListTile(
title: Text(snap['name']),
subtitle: Text(snap['email']),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ChatRoom(
friendName: snap['name'] ,
friendEmail: snap['email'],
friendUid: snap['uid'],
),
),
);
},
leading: Container(
height: 45,
width: 45,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white),
child: const Center(
child: Icon(Icons.person),
),
),
);
}
return Container();
},
);
} else if (snapshot.hasError) {
return const Center(
child: Text("Something went wrong!"),
);
} else {
return Container();
}
},
),
),
],
),
);
}
}
//..............................User Details Fetch here ??..........................................
class DrawerPage extends StatefulWidget {
const DrawerPage({Key? key}) : super(key: key);
#override
State<DrawerPage> createState() => _DrawerPageState();
}
class _DrawerPageState extends State<DrawerPage> {
#override
void initState() {
super.initState();
getUserData();
}
String name = '';
String email = '';
String password = '';
final currentUser = FirebaseAuth.instance.currentUser;
Future<void> getUserData() async {
final user = await FirebaseFirestore.instance
.collection('Users')
.doc(currentUser!.uid)
.get();
setState(() {
name = user.data()!['name'];
email = user.data()!['email'];
password = user.data()!['password'];
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Name: $name',
style: GoogleFonts.raleway(
fontWeight: FontWeight.normal, fontSize: 16),
),
const SizedBox(height: 10),
Text(
'Email: $email',
style: GoogleFonts.raleway(
fontWeight: FontWeight.normal, fontSize: 16),
),
const SizedBox(height: 10),
Text(
'Password: $password',
style: GoogleFonts.raleway(
fontWeight: FontWeight.normal, fontSize: 16),
),
],
),
),
);
}
}
second chatroom.dart file =================================
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:jobong/model/chatroom_model.dart';
class ChatRoom extends StatefulWidget {
final ChatRoomModel friendName;
final ChatRoomModel friendUid;
final ChatRoomModel friendEmail;
const ChatRoom({
Key? key,
required this.friendName, required this.friendUid ,
required this.friendEmail
}) : super(key: key);
#override
State<ChatRoom> createState() => _ChatRoomState();
}
class _ChatRoomState extends State<ChatRoom> {
void showToast(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
final email = FirebaseAuth.instance.currentUser!.email;
void sendMessage() async {
try{
await FirebaseFirestore.instance.collection('chats')
.doc(uid).collection('messages').doc()
.set({
'sender':email,
'receiver':widget.friendUid,
'message':_message.text.trim(),
'time':FieldValue.serverTimestamp(),
});
}on FirebaseAuthException catch (e) {
showToast('${e.message}');
}
}
final bool isMe = false;
final _message = TextEditingController();
final uid = FirebaseAuth.instance.currentUser!.uid;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Column(
children: [
Text(
widget.friendName.toString(),
style: GoogleFonts.lato(),
),
Text(
widget.friendEmail.toString(),
style: GoogleFonts.lato(),
),
],
),
),
body: Column(
children: [
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('chats')
.doc(uid)
.collection('messages')
.doc()
.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(color: Colors.blue),
);
} else {
return ListView.builder(
shrinkWrap: true,
reverse: true,
itemCount: snapshot.data!.doc.length,
itemBuilder: (BuildContext context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: isMe
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: isMe
? BorderRadius.circular(15.0)
: BorderRadius.circular(15.0),
color: isMe
? Colors.green[500]
: Colors.red[500]),
child: Center(
child: Text(_message.toString(),
style: isMe
? GoogleFonts.lato(color: Colors.black)
: GoogleFonts.lato(
color: Colors.white)),
),
),
],
),
);
},
);
}
},
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 8.0),
child: Container(
height: 60,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(25),
bottomRight: Radius.circular(25),
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
color: Colors.grey[900],
),
child: TextFormField(
controller: _message,
style: GoogleFonts.lato(color: Colors.white),
decoration: InputDecoration(
hintText: 'send a message ...',
hintStyle: GoogleFonts.lato(color: Colors.white),
border: InputBorder.none,
prefixIcon: const Icon(Icons.file_present_rounded,
color: Colors.white),
suffixIcon: GestureDetector(
onTap:sendMessage,
child: const Icon(Icons.near_me, color: Colors.white),
),
),
),
),
),
],
),
);
}
}

How to pass a variable (TextEditingController) to another class

class that i have the variable in
...
class _ActivitiesParticipantsState extends State<ActivitiesParticipants> {
final activityController = TextEditingController();
final user = FirebaseAuth.instance.currentUser!;
//Activities participants
List<String> docIDs = [];
//get docIDS
Future getDocId() async {
await FirebaseFirestore.instance
.collection(
activityController.text.trim(),
)
.get()
.then(
(snapshot) => snapshot.docs.forEach(
(element) {
docIDs.add(element.reference.id);
},
),
);
//stuff
}
#override
void dispose() {
activityController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: activityController,
decoration: InputDecoration(
labelText: 'e',
border: InputBorder.none,
),
),
GestureDetector(
onTap: () async {
setState(
() {
getDocId();
},
);
},
child: Container(
padding: EdgeInsets.all(
20,
),
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
),
child: Center(
child: Text(
'Test',
style: TextStyle(
color: Colors.white,
fontFamily: 'Quicksand',
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
),
),
Expanded(
child: FutureBuilder(
builder: (context, snapshot) {
return ListView.builder(
itemCount: wee(),
//docIDs.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: ListTile(
dense: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
tileColor: Color.fromARGB(255, 235, 235, 235),
title: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 20),
child: Column(
children: [
SizedBox(
height: 5,
),
Align(
alignment: Alignment.centerLeft,
child: Title(
color: Colors.black,
child: InterestedName(
documentID: docIDs[index]),
),
),
SizedBox(
height: 20,
),
],
),
),
),
);
},
);
},
),
),
],
),
),
),
);
}
}
...
How do I get the variable "activityController" to another class?
This other class is used to get Text to fill the ListTile
class that I want to get the variable
final String documentID;
InterestedName({required this.documentID});
#override
Widget build(BuildContext context) {
// get the collection
CollectionReference users = FirebaseFirestore.instance.collection('Project Koalas [test]');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(documentID).get(),
builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data =
snapshot.data!.data() as Map<String, dynamic>;
return Text(
'Name: ${data['name']}',
style: TextStyle(
fontSize: 16,
fontFamily: 'Quicksand',
fontWeight: FontWeight.w600),
);
}
return Text('loading...');
}),
);
}
}
I would like to get the variable to be able to get the collection name that I want to take data from, as the collection I would like to take from is dependent on the user's choice.
If there is any way else to somehow fill the List tile in the same class, please let me know how.
Any help appreciated!

List of text in one Card using ListView.builder twice and for loop?

With my current code, my list is put into separate cards. I need it to be in one. I'm using two ListView.builders and a loop. I believe that's what's causing the problem. Please tell me if I'm wrong.
Every time the user taps submit on my second TextField a new TextField appears, functionality I would like to keep one way or another.
I'm just staring out so any help if appreciated.
My end goal is to have a bullet point list but the bullet points aren't important right now.
Here's my code:
class PostNote extends StatefulWidget {
User user;
PostNote({
required this.user,
});
#override
State<PostNote> createState() => _PostNoteState();
}
class _PostNoteState extends State<PostNote> {
FirebaseFirestore firestore = FirebaseFirestore.instance;
TextEditingController titleController = TextEditingController();
final List<TextField> _textFields = [];
final List<TextEditingController> _controllers = [];
bool loading = false;
#override
void initState() {
super.initState();
_addTextField();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xFF162242),
elevation: 0,
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
Text(
"Title",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(
height: 15,
),
Container(
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: Colors.white,
),
padding: EdgeInsets.only(left: 10, right: 10),
child: TextField(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
textInputAction: TextInputAction.next,
style: TextStyle(
color: Color(0xFF192A4F),
fontSize: 18,
),
controller: titleController,
autofocus: true,
),
),
SizedBox(
height: 30,
),
Text(
"Notes",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(
height: 15,
),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: Colors.white,
),
child: ListView.builder( // HERE
shrinkWrap: true,
itemCount: _textFields.length,
itemBuilder: (_, index) {
return _textFields[index];
},
),
),
SizedBox(
height: 50,
),
loading
? Center(
child: CircularProgressIndicator(),
)
: Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
child: Text(
"Add Note",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color(0xFF162242)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
onPressed: () async {
for (var notesController in _controllers) // HERE {
if (titleController.text == "" ||
notesController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text("All fields are required")));
} else {
setState(() {
loading = true;
});
await FirestoreServiceEdit().insertNote(
titleController.text,
notesController.text,
widget.user.uid);
CollectionReference notes =
firestore.collection('notes');
QuerySnapshot allResults = await notes.get();
allResults.docs.forEach((DocumentSnapshot result) {
print(result.data());
});
if (!mounted) return;
setState(() {
loading = false;
});
Navigator.pop(context);
}
}
}),
),
]),
),
),
),
);
}
void _addTextField() {
final notesController = TextEditingController();
_textFields.add(
TextField(
decoration: InputDecoration(
prefix: Icon(
Icons.circle,
size: 8,
color: Colors.black,
),
),
autofocus: true,
controller: notesController,
onSubmitted: (_) => setState(() => _addTextField()),
),
);
_controllers.add(notesController);
}
}
class FirestoreServiceEdit{
FirebaseFirestore firestore = FirebaseFirestore.instance;
Future insertNote(String title, String notes, String? userId,)async{
try{
await firestore.collection('notes').add({
"title":title,
"notes":notes,
"userId":userId
});
} catch (e) {}
}
}
class NoteModelEdit {
String id;
String title;
String notes;
String userId;
NoteModelEdit({
required this.id,
required this.title,
required this.notes,
required this.userId
});
factory NoteModelEdit.fromJson(DocumentSnapshot snapshot){
return NoteModelEdit(
id: snapshot.id,
title: snapshot['title'],
notes: snapshot['notes'],
userId: snapshot['userId']
);
}
}
Home screen:
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("notes")
.where('userId', isEqualTo: user.uid)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
if (snapshot.data.docs.length > 0) {
return ListView.builder( // HERE
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
NoteModelEdit note =
NoteModelEdit.fromJson(snapshot.data.docs[index]);
return Card(
margin: EdgeInsets.only(top: 18, left: 15, right: 15),
child: Column(children: [
ListTile(
title: Center(
child: Container(
padding: EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 0.5),
),
),
child: Text(
note.title,
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.w600),
textAlign: TextAlign.center,
),
),
),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EditNoteScreen(),
));
},
),
SizedBox(
height: 15,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
note.notes,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w700),
),
),
SizedBox(
height: 15,
),
]),
);
});
Thank you for your time!
You will need to augment your logic to look at all the TextFields at the same time rather than one at a time and inserting a note for each.
if (titleController.text.isEmpty ||
_controllers.any((element) => element.text.isEmpty)) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text("All fields are required")));
} else {
setState(() {
loading = true;
});
}
await FirestoreServiceEdit().insertNote(
titleController.text,
_controllers.map((element) => element.text).join("\n"),
widget.user.uid);
you can do like this :
Widget listInCard() {
List testList = ["note1", "note2", "note3"];
return Card(
color: Colors.blue.shade200,
elevation: 5,
child: ListView.builder(
itemCount: testList.length,
itemBuilder: (context, index) {
return Text(testList[index]);
}),
);
}
The blue color is the Card and inside it, it is a list of notes.
You can also use Container instead of Card.

Flutter General dialog box - set state not working

I have an issue with my General Dialog Box. I would like to display a star. Then I would like to change it state when the star is taped and replace the icon by a yellow Star.
But is does not work. The Dialog Box is not refreshed so the icon is not changing. Please, can you look at the source code below and point me into the right direction please?
Many thanks.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:date_time_picker/date_time_picker.dart';
import 'package:gtd_official_sharped_focused/snackbar.dart';
String _isImportantInboxTask ;
String _isUrgentInboxTask ;
String inboxTaskDisplayed;
String isImportant = "false" ;
String isUrgent = "false" ;
String myProjectName ;
var taskSelectedID;
//---------------
//String _initialValue;
//_-----------------
var documentID;
var textController = TextEditingController();
var popUpTextController = TextEditingController();
class Inbox extends StatefulWidget {
Inbox({Key key}) : super(key: key);
#override
_InboxState createState() => _InboxState();
}
class _InboxState extends State<Inbox> {
GlobalKey<FormState> _captureFormKey = GlobalKey<FormState>();
bool isOn = true;
#override
Widget build(BuildContext context) {
void showAddNote() {
TextEditingController _noteField = new TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return CustomAlertDialog(
content: Container(
width: MediaQuery.of(context).size.width / 1.3,
height: MediaQuery.of(context).size.height / 4,
child: Column(
children: [
TextField(
controller: _noteField,
maxLines: 4,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1.0),
),
),
),
SizedBox(height: 10),
Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(25.0),
color: Colors.white,
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width / 1.5,
onPressed: () {
Navigator.of(context).pop();
CollectionReference users = FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.add({'task_Name': _noteField.text,'task_Status': 'Inbox' })
.then((value) => print("User Document Added"))
.catchError((error) =>
print("Failed to add user: $error"));
},
padding: EdgeInsets.fromLTRB(10.0, 15.0, 10.0, 15.0),
child: Text(
'Add Note',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
);
});
}
return Scaffold(
appBar: new AppBar(
title: new Text('Inbox Page'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.add_circle_outline,
color: Colors.white,
),
onPressed: () {
showAddNote();
// do something
},
),
],
),
drawer: MyMenu(),
backgroundColor: Colors.white,
body: Column(
//mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.height / 1.4,
width: MediaQuery.of(context).size.width,
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.where('task_Status', isEqualTo: 'Inbox')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView(
children: snapshot.data.docs.map((document) {
return Wrap(
children: [Card(
child: SwipeActionCell(
key: ObjectKey(document.data()['task_Name']),
actions: <SwipeAction>[
SwipeAction(
title: "delete",
onTap: (CompletionHandler handler) {
CollectionReference users = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.doc(document.id)
.delete()
.then((value) => print("Note Deleted"))
.catchError((error) => print(
"Failed to delete Task: $error"));
},
color: Colors.red),
],
child: Padding(
padding: const EdgeInsets.all(0.0),
child: ListTile(
leading: ConstrainedBox(
constraints: BoxConstraints(
minWidth: leadingIconMinSize,
minHeight: leadingIconMinSize,
maxWidth: leadingIconMaxSize,
maxHeight: leadingIconMaxSize,
),
child: Image.asset('assets/icons/inbox.png'),
),
title: GestureDetector(
child: Text(
//'task_Name' correspond au nom du champ dans la table
document.data()['task_Name'],
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
// Pour editer task
onDoubleTap: (){
taskSelectedID = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.doc(document.id);
//Dialog
return showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context)
.modalBarrierDismissLabel,
barrierColor: Colors.black45,
transitionDuration: const Duration(milliseconds: 20),
pageBuilder: (BuildContext buildContext,
Animation animation,
Animation secondaryAnimation) {
return Scaffold(
appBar: AppBar(
title: Text ('Edit Task'),
leading: InkWell(
child: Icon(Icons.close),
onTap:(){Navigator.of(context).pop();}
),
actions: [Padding(
padding: const EdgeInsets.fromLTRB(0, 0,16.0,0),
child: InkWell(
child: Icon(Icons.save),
onTap: () {
final loFormInbox = _captureFormKey
.currentState;
if (loFormInbox.validate()) {
loFormInbox.save();
CollectionReference users = FirebaseFirestore
.instance
.collection(
'Users')
.doc(FirebaseAuth
.instance
.currentUser.uid)
.collection(
'allTasks');
users
.add({
'task_Name': _valueTaskNameSaved,
})
.then((value) =>
print(
"Task Created"))
.catchError((
error) =>
print(
"Failed to add task: $error"));
showSimpleFlushbar(
context,
'Task Saved',
_valueTaskNameSaved,
Icons
.mode_comment);
loFormInbox.reset();
isImportant = 'false';
isUrgent = 'false';
}
}
),
)],
),
body: Center(
child: Container(
width: MediaQuery.of(context).size.width - 10,
height: MediaQuery.of(context).size.height - 80,
padding: EdgeInsets.all(20),
color: Colors.white,
child: Column(
children: [
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
//Test Energy et Time / Important /urgent
Material(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
//Important
FlatButton(
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isImportant =="true" ? Icon(Icons.star,color: Colors.orange,) :
Icon(Icons.star_border, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Important'),
],
)
),
onTap: () {
setState(() {
if (isImportant=='true'){
isImportant = 'false';}
else
{isImportant= 'true';
}
});
},
),
),
RaisedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Close",
style: TextStyle(color: Colors.white),
),
color: const Color(0xFF1BC0C5),
)
//++++++++++++++++
],
),
),
),
);
});
},
),
),
),
),
),
),
]
);
}).toList(),
);
}),
),
],
),
bottomNavigationBar: MyBottomAppBar(), //PersistentBottomNavBar(),
);
}
}
#override
Widget build(BuildContext context){
return _widget();
}
}
Thanks to your solution, I am able to do what I was willing to do. But now, I have an other issue. In the version 1 of my code, I am using this code
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
This part was working well. But after the modifications, I am getting an error. The error is about document.
Undefined name 'document'. Try correcting the name to one that is defined, or defining the name.
Please, can you help me with this so I can finalize this page. Thank you
So you want to change the color of icon on clicking it inside dialogBox,
but unfortunately you are using stateless widget Scaffold in return of showGeneralDialog builder so one thing that can possibly help is to make a separate StateFull Widget RatingDialogBox and use that in the builder.
Also instead of InkWell you can use IconButton
I will suggest you to use this package it is great
flutter_rating_bar
also feel free to comment is this doesn't satisfy your need

Flutter Firebase: not able update Database

I want to update my Collection with an NumberPicker in a Alert Dialog. I do not get any errors in code or from the emulator. When i press the button to update the code the terminal do not give any errors. Everything looks fine but for some reason i do not work. When you need more Information just leave a comment with what you excactly need. :)
import 'package:flutter/material.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
import 'package:testapp/services/Services.dart';
import 'models/Goals.dart';
class Statistics extends StatefulWidget {
#override
_StatisticsState createState() => _StatisticsState();
}
class _StatisticsState extends State<Statistics> {
int _currentFirstValue = 1;
int totalFirst;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 260,
child: StreamBuilder(
stream: FirestoreService().getGoals(),
builder: (context, AsyncSnapshot<List<Goal>> snapshot) {
if (snapshot.hasError || !snapshot.hasData) {
return Center(child: CircularProgressIndicator(
backgroundColor: Color(0XFF1954A1),
));
}
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
// ignore: missing_return
Goal goal = snapshot.data[index];
return Row(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
height: 230,
width: 350,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.grey[300],
offset: const Offset(0.5, 1),
blurRadius: 4.0,
spreadRadius: 0.1,
),
]),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text('WeekGoals', style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w500,
),),
SizedBox(width: 100),
SizedBox(
height: 20,
width: 87,
child: FlatButton(
child: Text('edit', style: TextStyle(
fontSize: 17,
color: Colors.yellow[700]
),),
onPressed: () {
return showDialog(
context: context,
barrierDismissible: true,
builder: (context) => AlertDialog(
content: Column(
children: <Widget>[
Text('weekly goals'),
NumberPicker.integer(
initialValue: _currentFirstValue,
minValue: 1,
maxValue: 100,
onChanged: (newGoal) => setState(() => {
_currentFirstValue = newGoal,
totalFirst = _currentFirstValue,
})
),
Row(
children: <Widget>[
RaisedButton(
child: Text('edit goals'),
onPressed: () async {
Goal goal = Goal(
weekActivityGoal: totalFirst,
);
await FirestoreService().updateGoal(goal);
Navigator.pop(context, false);
},
),
FlatButton(
child: Text('Close'),
onPressed: () {
Navigator.pop(context, false);
},
)
],
)
],
),
)
);
},
),
)
],
),
SizedBox(height: 10),
Row(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 17.5),
child: CircularPercentIndicator(
header: Text('activitys', style: TextStyle(
fontSize: 17,
),),
radius: 130,
progressColor: Colors.red,
lineWidth: 8,
backgroundColor: Colors.grey[200],
percent: goal.weekActivity*100/goal.weekActivityGoal,
center: Text('${goal.weekActivity}/${goal.weekActivityGoal}'),
),
),
],
),
],
),
),
],
);
});
}),
),
);
}
}
Here this has been helping a lot of people try i out might help you too.
StreamBuilder(
stream: Firestore.instance.collection('Hearings').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) return Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Select lot');
case ConnectionState.waiting:
return Text('Awaiting bids...');
case ConnectionState.active:
{
print('active');
return Text('${snapshot.data}');
}
case ConnectionState.done:
{
print('Done');
return _buildList(context, snapshot.data);
}
}
return null;
}),
));
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
return ListView(
padding: const EdgeInsets.only(top: 20.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
);
}
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
return Padding(
key: ValueKey(record.name),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text(record.name),
trailing: Text(record.votes.toString()),
onTap: () => Firestore.instance.runTransaction((transaction) async {
final freshSnapshot = await transaction.get(record.reference);
final fresh = Record.fromSnapshot(freshSnapshot);
await transaction
.update(record.reference, {'votes': fresh.votes + 1});
}),
),
),
);
}
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['name'] != null),
assert(map['votes'] != null),
name = map['name'],
votes = map['votes'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
#override
String toString() => "Record<$name:$votes>";
}
This is where the link this info came from.