FLUTTER- I want to post and fetch datas from database - database

I am working on a flutter project and I want to fetch datas which I post to database. I can post successfully (I can see them in my database) but I cannot fetch data. I want your help... please help me... the codes, explanation and the problem below here.
the code:
class GetId {
String id;
GetId({this.id});
factory GetId.fromJson(Map<String, dynamic> json) {
return GetId(
id: json["id"],
);
}
}
Future<GetId> sendData() async {
_DenemeState controls = new _DenemeState();
final response = await http.post(
"https://www.ekrts.com.tr/bloom/get.php",
body: {
"id": "${controls.idController.text.toString()}"
},
);
if (response.statusCode == 200) {
return GetId.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load album');
}
}
class _DenemeState extends State<Deneme> {
TextEditingController nameController = TextEditingController();
TextEditingController surnameController = TextEditingController();
TextEditingController idController = TextEditingController();
Future<GetId> futureGetId;
Container _getValues() {
return Container(
child: Column(
children: <Widget>[
Text(
nameController.text.toString(),
),
Text(
'textfield değeri ' + idController.text.toString(),
),
Text(
"Response: ",
)
],
),
);
}
#override
void initState() {
super.initState();
futureGetId = sendData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Scaffold(
appBar: AppBar(
title: Text("Register"),
),
body: Container(
child: Center(
child: Column(
children: <Widget>[
Text(
"ad",
style: TextStyle(fontSize: 18.0),
),
TextField(
controller: nameController,
decoration: InputDecoration(hintText: 'ad'),
),
Text(
"soyad",
style: TextStyle(fontSize: 18.0),
),
TextField(
controller: surnameController,
decoration: InputDecoration(hintText: 'soyad'),
),
Text(
"id",
style: TextStyle(fontSize: 18.0),
),
TextField(
controller: idController,
decoration: InputDecoration(hintText: 'id'),
),
RaisedButton(
child: Text("Register"),
onPressed: () {
setState(() {
_getValues();
sendData();
});
},
),
_getValues(),
FutureBuilder<GetId>(
future: futureGetId,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.id);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
],
),
),
),
),
);
}
}
Explanation:
GetId class: This class contains the data from network request
Future sendData(): This class connects my database and post the data to database, I can see them.
Container _getValues(): I created to see my data from the database on screen.
And my problem, I cannot see the data on emulator screen but I can post and see on database. I hope, I could explain my problem... please help me...

FirebaseAuth.instance.currentUser().then((user) {
id= user.uid;
});
i hope you are asking for something like this. you can load the user id to id variable from this.

Related

How would I show my posts from my firestore?

Okay so my profile posts are working as intended right here, I am showing the users posts that only they have made to their very own profile
Now here is the code doing that
static Future<List<Post>> getUserPosts(String currentUserId) async {
QuerySnapshot userPostsSnap = await postsRef
.doc(currentUserId)
.collection('userPosts')
.orderBy('timestamp', descending: true)
.get();
List<Post> userPosts =
userPostsSnap.docs.map((doc) => Post.fromDoc(doc)).toList();
return userPosts;
}
and also to show them to the profile page as you see in the image:
showProfilePosts(UserModel author) {
return Expanded(
child: ListView.builder(
shrinkWrap: true,
physics: AlwaysScrollableScrollPhysics(),
itemCount: _allPosts.length,
itemBuilder: (context, index) {
return PostContainer(
post: _allPosts[index],
author: author,
currentUserId: widget.currentUserId,
);
}),
);
}
getAllPosts() async {
List<Post> userPosts =
await DatabaseMethods.getUserPosts(widget.visitedUserId);
if (mounted) {
setState(() {
_allPosts = userPosts;
});
}
}
#override
void initState() {
super.initState();
getAllPosts();
}
now my goal is to show every single post made by every user (I'm creating one big forum) so how can I show every single post made by everyone in the database to my home screen? My database also looks like this for some visuals, would I have to loop through?
here is my Home screen's code, where I wish to display every users posts
class HomeScreen extends StatefulWidget {
final String currentUserId;
const HomeScreen({Key? key, required this.currentUserId}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List _homeScreenPosts = [];
bool _loading = false;
buildHomeScreenPosts(Post post, UserModel author) {
return PostContainer(
post: post,
author: author,
currentUserId: widget.currentUserId,
);
}
showHomeScreenPosts(String currentUserId) {
List<Widget> homePostsList = [];
for (Post post in _homeScreenPosts) {
homePostsList.add(
FutureBuilder(
future: usersRef.doc(post.authorId).get(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
UserModel author = UserModel.fromSnap(snapshot.data);
return buildHomeScreenPosts(post, author);
} else {
return SizedBox.shrink();
}
},
),
);
}
return homePostsList;
}
setupHomeScreenPosts() async {
setState(() {
_loading = true;
});
List homeScreenPosts =
await DatabaseMethods.getHomeScreenPosts(widget.currentUserId);
if (mounted) {
setState(() {
_homeScreenPosts = homeScreenPosts;
_loading = false;
});
}
}
#override
void initState() {
super.initState();
setupHomeScreenPosts();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchScreen(
currentUserId: widget.currentUserId,
),
),
);
},
icon: Icon(Icons.search),
),
],
automaticallyImplyLeading: false,
title: Text('Home'),
centerTitle: true,
),
body: RefreshIndicator(
onRefresh: () => setupHomeScreenPosts(),
child: ListView(
physics: BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
children: [
_loading ? LinearProgressIndicator() : SizedBox.shrink(),
SizedBox(height: 5),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 5),
Column(
children: _homeScreenPosts.isEmpty && _loading == false
? [
SizedBox(height: 5),
Padding(
padding: EdgeInsets.symmetric(horizontal: 25),
child: Text(
'There is No New posts',
style: TextStyle(
fontSize: 20,
),
),
),
]
: showHomeScreenPosts(widget.currentUserId),
),
],
)
],
),
),
);
}
}
Firebase does not have the a concept of "tables" the way relational/sql databases do. I.e. there is not a built-in method to access all documents labelled as a "post".
Because of this, you'll need to access each post through each of the user documents.
Assuming you have a List of all of your user Id's called allUserIds, then you can do something like the following:
List<Post> allPostsForAllUsers = [];
allUserIds.forEach((id) {
allPostsForAllUsers.addAll(await getUserPosts(id));
}
Okay so I figured it out myself, all I had to do was call the collectionGroup 'userPosts' like so
static Future<List<Post>> getHomeScreenPosts(String currentUserId) async {
QuerySnapshot homePostsSnap = await FirebaseFirestore.instance
.collectionGroup('userPosts')
.orderBy('timestamp', descending: true)
.get();
List<Post> homeScreenPosts =
homePostsSnap.docs.map((doc) => Post.fromDoc(doc)).toList();
return homeScreenPosts;
}

How to hide a floatingActionButton after insert data flutter?

I use sqflite for flutter database management. In particular, I would like the user to enter the data only once and therefore I would need to hide and disable the button only once the data has been entered. How can I do?
Home Page, where is the button
class Casa extends StatefulWidget {
static const routeName = '/';
#override
_CasaState createState() => _CasaState();
}
class _CasaState extends State<Casa> {
DataRepository _repository;
#override
void initState() {
super.initState();
_repository = SqlRepository();
}
#override
void dispose() async {
await _repository.closeDB();
super.dispose();
}
void getNewItem(BuildContext context) async {
Attivita newItem =
await Navigator.pushNamed<Attivita>(context, AddItemScreen.routeName);
if (newItem != null) {
await _repository.add(newItem);
setState(() {});
}
}
void switchAndUpdate(Attivita item) async {
await _repository.put(item.id, item);
setState(() {});
}
void delete(Attivita item) async {
await _repository.delete(item.id);
setState(() {});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.lightBlue[900],
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add, color: Colors.lightBlue[900],),
backgroundColor: Colors.white,
onPressed: () {
getNewItem(context);
},
),
body:
FutureBuilder<List<Attivita>>(
future: _repository.getAll(),
builder:
(BuildContext context, AsyncSnapshot<List<Attivita>> snapshot) {
return ListView.builder(
padding: EdgeInsets.all(8),
itemCount: snapshot.data == null ? 0 : snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
key: UniqueKey(),
background: DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
child: Align(
alignment: Alignment(-0.9, 00),
child: Icon(
Icons.delete,
color: Colors.white,
),
),
),
direction: DismissDirection.startToEnd,
onDismissed: (direction) {
Attivita item = snapshot.data[index];
snapshot.data.removeAt(index);
delete(item);
},
child: Card(
child: ListTile(
title: Text(snapshot.data[index].nome, style: TextStyle(color: Colors.lightBlue[900]),),
onTap: () {
Navigator.pushNamed(context, DettaglioScreen.routeName, arguments: snapshot.data[index]);
},
onLongPress: () {
switchAndUpdate(snapshot.data[index]);
},
),
),
);
},
);
},
)
),
);
}
}
so i have to add some details, because it is written that "it looks like your post is mostly code; please add some more details"
To check if user put so data you can use:
Use sharedPreferences and store bool value if user entered data.
On initState check if database contains data if yes it means user put some data and you can hide button.
I don't use Sqlite in flutter but I think you can use
List<Map<String, dynamic>> result;
result = await db.query(tableName);
isNotData = result.isEmpty;
Or something similar :) You can do it
Choose one way and store bool value eg. in bool isNotData
When you will have bool value about data you can write:
In _CasaState above initState: bool isNotData;
and in Scaffold in floatingActionButton property:
Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
floatingActionButton: isNotData
? FloatingActionButton(
onPressed: () {},
)
: null,
body: Center(
),
),
),

How to display my results in a list of cards from firestore with flutter

I am currently working on a flutter app. And in my database I have a collection and in that I have documents. Each document has a subcollection. In that collection I have two documents. Post1 and Post2. I have problems with fetching that data and displaying that in a list of cards: So I want to display them in a list of cards.
Every Card has in one side, the data from post1 and in the other side, the data for post2
I tried it with a futurebuilder, but I just cant do it. Would appreciate any help.
My firestore DataBase:
I have that for every document. So for the second document, I have also the same structure.
My code for displaying the list:
final generalreference = Firestore.instance.collection("General");
showpics() {
return FutureBuilder (
future: generalreference.getDocuments(),
builder: (context, querySnapshot) {
if (!querySnapshot.hasData) {
return Center(
child: Text(
"Loading...",
style: TextStyle(
fontFamily: "Montesserat",
fontWeight: FontWeight.w700,
fontSize: 40.0,
fontStyle: FontStyle.italic,
),
));
}
List<PostList> postsresult = [];
//QuerySnapshot eachitem = await generalreference.getDocuments(); \\ I am doing something wrong here
querySnapshot.data.documents.forEach((element) async {
DocumentSnapshot post1 = await generalreference
.document(element.documentID)
.collection("posts")
.document("post1")
.get();
Posts eachpost = Posts.fromDocument(post1);
PostList postList = PostList(eachpost);
postsresult.add(postList);
//print("the posts is $postsresult");
});
print("the posts is $postsresult");
return ListView(children: postsresult);
});
}
My PostList class:
class PostList extends StatelessWidget {
final Posts picture1;
PostList(this.picture1);
#override
Widget build(BuildContext context) {
return GestureDetector(
child: Card(
elevation: 20.0,
child: Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CircleAvatar(
radius: 20.0,
backgroundImage: NetworkImage(picture1.pic),
),
}
My posts model
class Posts{
final String uid;
final String email;
final String username;
final String id;
final String pic;
Posts( {
this.uid,
this.email,
this.username,
this.id,
this.pic
});
factory Posts.fromDocument(DocumentSnapshot doc){
return Posts(
uid: doc['uid'],
email: doc['email'],
username: doc['username'],
pic: doc['Pic'],
id: doc.documentID );
}
}
I am not getting any errors, I just cant see my pictures
So, i solved it in using a listview.builder as suggested by Uni, That solved my problem
Future<List<Post2>> getposts2() async {
var eachdocument = await generalreference.getDocuments();
List<Post2> posts = [];
for (var document in eachdocument.documents) {
DocumentSnapshot myposts = await generalreference
.document(document.documentID)
.collection("posts")
.document("post2")
.get();
print(myposts['Pic']);
Post2 post = Post2(myposts['Pic']);
posts.add(post);
}
return posts;
}
showpics() {
return FutureBuilder(
future: Future.wait([getposts(), getposts2()]),
builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
if (!snapshot.hasData) {
return Center(
child: Text(
"Loading...",
style: TextStyle(
fontFamily: "Montesserat",
fontWeight: FontWeight.w700,
fontSize: 40.0,
fontStyle: FontStyle.italic,
),
));
}
return ListView.builder(
itemCount: snapshot.data[0].length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
child: Card(
elevation: 20.0,
child: Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CircleAvatar(
radius: 20.0,
backgroundImage:
NetworkImage(snapshot.data[0][index].picture),
),

How do I access separate children from Firebase database in Flutter?

Hi I am currently trying to access a child of my database in Flutter so that I can link it to another child. I am able to pull the data from one child, but unable to link this data with my other child. I want to be able to access a field of the 'Record' child and link to the 'Volunteer' child using the "volunteer" field but am unable to get them to link together. Any help would be appreciated!
The database structure is as follows:
This is the code for My Volunteer class:
class Volunteer {
String volunteerID;
String name;
String role;
Volunteer(this.volunteerID, this.name, this.role);
Volunteer.fromSnapshot(DataSnapshot snapshot)
: volunteerID = snapshot.key,
name = snapshot.value["name"],
role = snapshot.value["role"];
toJson() {
return {
"key": volunteerID,
"name": name,
"role": role
};
}
}
And this is the code for my UI:
class SignInPageState extends State<SignInPage> {
List<Volunteer> volunteers;
Volunteer volunteer;
DatabaseReference dbRef;
DatabaseReference volunteerRef;
DatabaseReference recordRef;
#override
void initState() {
super.initState();
volunteers = new List();
volunteer = Volunteer("","", "");
final FirebaseDatabase database = FirebaseDatabase.instance;
dbRef = database.reference();
volunteerRef = database.reference().child('volunteer');
recordRef = database.reference().child('record');
dbRef.onChildAdded.listen(_onEntryAdded);
dbRef.onChildChanged.listen(_onEntryChanged);
volunteerRef.once().then((DataSnapshot snapshot) {
Map<dynamic, dynamic> getMap = snapshot.value;
getMap.forEach((key, values) {
String volunteerRecord = recordRef.child('volunteer').toString();
if (volunteerRecord == volunteer.volunteerID){
volunteer.role = volunteerRecord;
}
volunteers.add(volunteer);
});
});
}
_onEntryAdded(Event event) {
setState(() {
volunteers.add(Volunteer.fromSnapshot(event.snapshot));
});
}
_onEntryChanged(Event event) {
var old = volunteers.singleWhere((entry) {
return entry.volunteerID == event.snapshot.key;
});
setState(() {
volunteers[volunteers.indexOf(old)] = Volunteer.fromSnapshot(event.snapshot);
});
}
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.all(10.0),
color: Colors.white,
child: Column(
children: <Widget>[
Expanded(
flex: 8,
child: Container(
child: FirebaseAnimatedList(
query: volunteerRef,
itemBuilder: (BuildContext context, DataSnapshot snapshot,
Animation<double> animation, int index) {
return new ListTile(
title: Text(
(volunteers[index].name + " " + volunteers[index].role),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold ,color: Color.fromRGBO(139, 195, 68, 1)),
),
onTap: () {
SuccessSignInPage(volunteers[index].name);
},
);
},
),
)
),
],
)),
),
);
}
void Back() async {
await Navigator.of(context).pop();
}
void SuccessSignInPage(String name) async {
var route = new MaterialPageRoute(
builder: (BuildContext context) => new SignInSuccessPage(value: name));
await Navigator.of(context).push(route);
}
}

Flutter textformfield auto de-focus

This is the function I'm using to get a form displayed on my screen.
Form getNewLoanForm() {
return new Form(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new TextFormField(
decoration: new InputDecoration(labelText: 'Loan name'),
validator: (value) {
if (value.isEmpty) {
return 'Enter name';
} else {
return null;
}
},
onSaved: (value) => _loanName = value,
),
new Container(height: 16.0),
new RaisedButton(
child: new Text(
'ADD',
style: new TextStyle(color: Colors.white, fontSize: 17.0),
),
onPressed: addNewLoan,
color: Colors.blue,
)
],
),
);
}
Everything works fine up unit now. The problem starts when I add
final formKey = new GlobalKey<FormState>();
I declare this varial in class level. and use it in form.
return new Form(
key: formKey,
Like this and now the TextFormField starts to behave weirdly. Now if I select the text field it deselects itself.
Now keep in mind that this doesn't happen if I make this page my root page. But I'm pushing this page from my root page. If I make this page my root page the problem doesn't occur there.
Any idea what's wrong here?
Okay I'm putting my whole class
import 'package:flutter/material.dart';
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
import 'package:intl/intl.dart';
class NewLoan extends StatelessWidget {
String _loanName;
String _dateCreated;
final formKey = new GlobalKey<FormState>();
void addNewLoan() {}
Form getNewLoanForm(BuildContext context) {
final dateFormat = DateFormat("dd/MM/yyyy");
return new Form(
// key: formKey,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new TextFormField(
decoration: new InputDecoration(labelText: 'Loan name'),
validator: (value) {
if (value.isEmpty) {
return 'Enter name';
} else {
_loanName = value;
return null;
}
},
),
new Container(height: 16.0),
DateTimePickerFormField(
decoration: new InputDecoration(labelText: 'Date'),
format: dateFormat,
dateOnly: true,
onChanged: (date) {
print('Selected date ${date.toString()}');
Scaffold
.of(context)
.showSnackBar(SnackBar(content: Text('$date')));
},
),
new Container(height: 16.0),
new RaisedButton(
child: new Text(
'ADD',
style: new TextStyle(color: Colors.white, fontSize: 17.0),
),
onPressed: addNewLoan,
color: Colors.blue,
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text('New Loan'),
),
body: new Container(
padding: new EdgeInsets.all(20.0),
child: getNewLoanForm(context),
),
);
}
}
My Root page
import 'dart:async';
import 'package:firebase/new_loan.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'auth.dart';
import 'current_balance_page.dart';
import 'dart:io' show Platform;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
class HomePage extends StatefulWidget {
HomePage({this.auth, this.onSignOut});
final BaseAuth auth;
final VoidCallback onSignOut;
#override
_HomePageState createState() => _HomePageState();
}
FirebaseApp app;
Future<FirebaseApp> firebaseApp() async {
final FirebaseApp app = await FirebaseApp.configure(
name: 'hisab-442a2',
options: Platform.isIOS
? const FirebaseOptions(
googleAppID: '1:18726312:ios:1b7829f2ac180d28',
gcmSenderID: '75461431231231291692',
databaseURL: 'https://hisab-44s2a2.firebaseio.com',
)
: const FirebaseOptions(
googleAppID: '1:297855924061:android:669871c998cc21bd',
apiKey: 'AIzaSyD_shO5mfO9lhy2TVWhfo1VUmARKlG4suk',
databaseURL: 'https://hisab-442a2.firebaseio.com',
),
);
return app;
}
enum Balancestatus { checking, found, noBalance }
class _HomePageState extends State<HomePage> {
Balancestatus status = Balancestatus.checking;
DatabaseReference _databaseRef;
#override
void initState() {
super.initState();
getDatabaseRef();
}
void getDatabaseRef() async {
app = await firebaseApp();
final FirebaseDatabase database = new FirebaseDatabase(app: app);
_databaseRef = database.reference();
_databaseRef.child('ccurrent_balance').once().then((DataSnapshot snapshot) {
print('Current balance ${snapshot.value}');
int balance = snapshot.value;
setState(() {
if (balance == null || balance == 0) {
status = Balancestatus.noBalance;
} else {
status = Balancestatus.found;
}
});
});
}
Future _signOut() async {
try {
await widget.auth.singOut();
widget.onSignOut();
} catch (e) {
print('Error signing out: $e');
}
}
void balanceSet() {
setState(() {
status = Balancestatus.checking;
});
}
#override
Widget build(BuildContext context) {
switch (status) {
case Balancestatus.checking:
return new WelcomePage(onSignOut: _signOut);
case Balancestatus.found:
// return new NewLoan();
return new LoanList(onSignOut: _signOut);
case Balancestatus.noBalance:
return CurrentBalancePage(
databaseRef: _databaseRef,
balanceSet: balanceSet,
);
default:
return new WelcomePage(onSignOut: _signOut);
}
}
}
class LoanList extends StatelessWidget {
final VoidCallback onSignOut;
LoanList({this.onSignOut});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text('Loans'),
actions: <Widget>[
new FlatButton(
child: new Text(
'Logout',
style: new TextStyle(fontSize: 17.0, color: Colors.white),
),
onPressed: onSignOut,
)
],
),
body: new Container(
padding: EdgeInsets.all(20.0),
alignment: Alignment.bottomCenter,
child: new RaisedButton(
child: new Text(
'New Loan',
style: new TextStyle(color: Colors.white, fontSize: 17.0),
),
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => NewLoan()));
},
color: Colors.blue,
),
),
);
}
void addNewLoan() {
print('Add new Loan');
}
}
class WelcomePage extends StatelessWidget {
final VoidCallback onSignOut;
WelcomePage({this.onSignOut});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text('Welcome'),
actions: <Widget>[
new FlatButton(
child: new Text(
'Logout',
style: new TextStyle(fontSize: 17.0, color: Colors.white),
),
onPressed: onSignOut,
)
],
),
body: new Container(
child: new Center(
child: new Text(
'Checking',
style: new TextStyle(fontSize: 32.0),
),
),
),
);
}
}

Resources