Cant check if user account exists? - flutter

Helo, I am trying to check if user's account exists, if no, I want to run text 'account is deleted'.
But the problem is that when I start the app there is screen for existing account and only after reset I can get the real result.
Looks like check for account is done after running app for the first time, but I don't know where is the mistake.
Here is the code, thank you in advance:
class CheckIfDeletedAccount extends StatelessWidget {
String isAccountDeleted;
getData() async {
var userType = await Firestore.instance
.collection('users')
.where('userEmail', isEqualTo: email)
.getDocuments();
userType.documents.forEach((result) {
log(result.data["deleted"]);
isAccountDeleted = result.data["deleted"].toString();
});
}
#override
Widget build(BuildContext context) {
getData();
//log(isAccountDeleted);
if (isAccountDeleted == "true") {
return Scaffold(
body: Container(
child: Center(
child: Text("account is deleted"),
),
),
);
}
return MaterialApp(
theme: themeData,
home: Scaffold(
body: Bar(),
),
);
}
}

You need to wait for the result from Firebase. You are trying to build the widget before the isAccountDeleted is initialized.
In your scenario, you can use FutureBuilder as follows:
class CheckIfDeletedAccount extends StatelessWidget {
String isAccountDeleted;
Future<String> getData() async {
var userType = await Firestore.instance
.collection('users')
.where('userEmail', isEqualTo: email)
.getDocuments();
userType.documents.forEach((result) {
log(result.data["deleted"]);
isAccountDeleted = result.data["deleted"].toString();
});
return isAccountDeleted;
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if(snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
final isAccountDeleted = snapshot.data;
if (isAccountDeleted == "true") {
return Scaffold(
body: Container(
child: Center(
child: Text("account is deleted"),
),
),
);
}
return MaterialApp(
theme: themeData,
home: Scaffold(
body: Bar(),
),
);
}
return Center(child: const CircularProgressIndicator());
},
);
}
}

Based on savke comment you can use the following code using FutureBuilder:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class CheckIfDeletedAccount extends StatelessWidget {
Future getData() async {
String isAccountDeleted;
var userType = await Firestore.instance
.collection('users')
.where('userEmail', isEqualTo: email)
.getDocuments();
userType.documents.forEach((result) {
log(result.data["deleted"]);
isAccountDeleted = result.data["deleted"].toString();
});
return isAccountDeleted;
}
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: themeData,
home: Scaffold(
body: FutureBuilder(
future: getData(),
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
strokeWidth: 6,
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
),
);
} else {
if (snapshot.data == "true") {
return Container(
child: Center(
child: Text("account is deleted"),
),
);
}
else {
return Bar();
}
}
}),
));
}
}

Related

Why can i see black screen when using BlocBuilder though i have taken all possible measures?

This is my main file, I am trying to check for internet connection.And showing dialog if there is no internet connection using flutter cubit.
But the only hurdle is for a flicker of second the screen goes black and then dialog is displayed , how can i avoid this?
main.file
void main() {
runApp(BlocProvider(
create: (BuildContext context) => ConnectivityCubit()..checkConnectivity(),
lazy: false,
child: MaterialApp(home: MyApp()),
));
}
class MyApp extends StatelessWidget {
MyApp({super.key});
bool _isDialogDisplayed = false;
#override
Widget build(BuildContext context) {
return BlocConsumer<ConnectivityCubit, ConnectivityState>(
listener: (context, state) {
if (state == ConnectivityState.disconnected) {
_isDialogDisplayed = true;
showDialog(
context: context,
builder: (context) => const AlertDialog(
title: Text('No Internet'),
content: Text('Please check your internet connection.'),
),
);
}
if (state == ConnectivityState.connected &&
_isDialogDisplayed == true) {
Navigator.of(context).pop();
_isDialogDisplayed = false;
}
},
builder: (context, state) {
if (state == ConnectivityState.init) {
return const CircularProgressIndicator();
}
return MaterialApp( // <-- This is causing problem
home: Scaffold(
body: state == ConnectivityState.connected
? const Center(
child: Text('Hello World'),
)
: const Center(child: CircularProgressIndicator()),
),
);
},
);
}
}
cubit.file
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
enum ConnectivityState { connected, disconnected, init }
class ConnectivityCubit extends Cubit<ConnectivityState> {
final Connectivity _connectivity = Connectivity();
StreamSubscription<ConnectivityResult>? _subscription;
late Stream<ConnectivityResult> streamValue;
ConnectivityCubit() : super(ConnectivityState.init) {
streamValue = _connectivity.onConnectivityChanged;
_subscription = _connectivity.onConnectivityChanged.listen((result) {
if (result == ConnectivityResult.none) {
emit(ConnectivityState.disconnected);
} else {
emit(ConnectivityState.connected);
}
});
}
checkConnectivity() async {
final result = await _connectivity.checkConnectivity();
if (result == ConnectivityResult.none) {
emit(ConnectivityState.disconnected);
} else {
emit(ConnectivityState.connected);
}
}
#override
Future<void> close() {
_subscription?.cancel();
return super.close();
}
}
I have tried to simply use this way
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello World'),
)),
);
The above code solves black screen issue but it will show Hello World for fraction of second i.e because of the time taken to build dialog by the BlocListener. To overcome that I tried the above method. Though i have things wrapped inside the MaterialApp why do i see black screen?
you want builder part in check status and then showDialog()
MyApp({super.key});
bool _isDialogDisplayed = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: BlocConsumer<ConnectivityCubit, ConnectivityState>(
listener: (context, state) {
if (state == ConnectivityState.disconnected) {
_isDialogDisplayed = true;
showDialog(
context: context,
builder: (context) => const AlertDialog(
title: Text('No Internet'),
content: Text('Please check your internet connection.'),
),
);
}
if (state == ConnectivityState.connected &&
_isDialogDisplayed == true) {
Navigator.of(context).pop();
_isDialogDisplayed = false;
}
},
builder: (context, state) {
if (state == ConnectivityState.init) {
return const CircularProgressIndicator();
}
else if(state == ConnectivityState.disconnected){
_isDialogDisplayed = true;
showDialog(
context: context,
builder: (context) => const AlertDialog(
title: Text('No Internet'),
content: Text('Please check your internet connection.'),
),
);
}
},
);
);
}
}

Retrieving Firestore data in ListView but Failing

Currently struggling to make a ListView data retrieved from Firestore.
I am trying to get "kids name" saved under in the firestore as linked photo.
Firestore
No error message is shown up but the data is not retrieved correctly and shown blank screen...hope anyone can correct my code!
and here is my code:
class kidsNamePick extends StatefulWidget {
#override
_kidsNamePickState createState() => _kidsNamePickState();
}
class _kidsNamePickState extends State<kidsNamePick> {
List<Memo> kidsnamelist = [];
Future<void>fetchMemo()async{
final kidsnames = await FirebaseFirestore.instance.collection('useraccount').doc(FirebaseAuth.instance.currentUser!.uid)
.collection('kidsname').get();
final docs = kidsnames.docs;for (var doc in docs){
Memo fetchMemo = Memo(kidsname: doc.data()['kids name'],
);
kidsnamelist.add(fetchMemo);}
setState(() {
});}
#override
void initState(){
super.initState();
fetchMemo();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add/Select Kids'),
),
body: ListView.builder(
itemCount: kidsnamelist.length,
itemBuilder: (context, index){
return ListTile(
title: Text(kidsnamelist[index].kidsname),
);
},
)
);
}
}
The best way to call future method is using FutureBuilder, first change your fetchMemo to this:
Future<List<Memo>> fetchMemo() async {
try {
final kidsnames = await FirebaseFirestore.instance
.collection('useraccount')
.doc(FirebaseAuth.instance.currentUser!.uid)
.collection('kidsname')
.get();
final docs = kidsnames.docs;
return docs
.map((doc) => Memo(
kidsname: doc.data()['kids name'],
))
.toList();
} catch (e) {
return [];
}
}
then change your build method to this:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add/Select Kids'),
),
body: FutureBuilder<List<Memo>>(
future: fetchMemo(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<Memo> data = snapshot.data ?? [];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index].kidsname),
);
},
);
}
}
},
),
);
}

Appbar should show number of records using futurebuilder in flutter

I have just created a demo for better understanding future builder
scaffold body showing all users from api and appear should be shown with number of users
appear's title showing 0 when loaded but does not change...what to do to rebuild it
here is my code
class _withmodelState extends State<withmodel> {
List<UserModel> userlist=[];
Future<List<UserModel>> getdata() async {
final resp =
await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (resp.statusCode == 200) {
print('i ma called');
List<dynamic> dlist = json.decode(resp.body);
await Future.delayed(Duration(seconds: 2));
userlist= dlist.map((e) => UserModel.fromJson(e)).toList();
return userlist;
}
return userlist;
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(title: Text("Total users="+userlist.length.toString()),),
body: MyBody(
//MyBody returning FutureBuilder for showing userlist array;
),
));
}
You can use ChangeNotifier like this, first create a class like this:
class WithmodelDecl with ChangeNotifier {
ValueNotifier<int> totalUsers = ValueNotifier<int>(0);
}
WithmodelDecl withmodeldecl = new WithmodelDecl();
then use it like this:
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
child: ValueListenableBuilder<int>(
valueListenable: withmodeldecl.totalUsers,
builder: (context, value, _) {
return AppBar(
title: Text("Total users=" + value.toString()),
);
}),
preferredSize: AppBar().preferredSize),
body: MyBody(
//MyBody returning FutureBuilder for showing userlist array;
),
));
and finally change your getdata to this:
Future<List<UserModel>> getdata() async {
final resp =
await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (resp.statusCode == 200) {
print('i ma called');
List<dynamic> dlist = json.decode(resp.body);
await Future.delayed(Duration(seconds: 2));
userlist= dlist.map((e) => UserModel.fromJson(e)).toList();
withmodeldecl.totalUsers.value = userlist.length;
return userlist;
}
return userlist;
}
You also need to rebuild the Text widget, that you are using to show the count, when the count is available, i.e., the Future completes.
You need to wrap that Text widget with FutureBuilder like this:
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: FutureBuilder<List<UserModel>>(
future: getdata(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
final List<UserModel> userlist = snapshot.data!;
return Text("Total users= ${userlist.length}");
// it's better to use String interpolation than "Total users=" + snapshot.data!.length.toString()
} else {
// return loading widget
}
},
),
),
body: MyBody(
//MyBody returning FutureBuilder for showing userlist array;
),
),
);
It is better to have the Future in a variable, and then use it like this, to avoid unwanted and repeated calling of it whenever the build() method is called:
late final Future<List<UserModel>> _userListFuture;
And initialize it in your initState(), like this:
#override
void initState() {
super.initState();
_userListFuture = Future<List<UserModel>>(getdata);
}
And use it with your FutureBuilder like this:
FutureBuilder<List<UserModel>>(
future: _userListFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// return your widget showing data
} else {
// return loading widget
}
},
)

I am failing to get data from cloud firestore while using flutter

At first, when i started writing my calls to get data from firestore, it worked. But when i tried writing more docs to my collection, it failed to bring data for the docs i recently added. Then, when i deleted the first one i added, i stopped receiveing data from firestore all together. I have tried several methods, but have all ended in failure.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class collect extends StatefulWidget {
#override
_collectState createState() => _collectState();
}
class _collectState extends State<collect>
{
Future _data;
void initState()
{
super.initState();
_data = getStuff();
}
Future getStuff()
async {
var firestore = FirebaseFirestore.instance;
QuerySnapshot qn = await firestore.collection("buses").get();
return qn.docs;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _data,
builder: (_, snapshot)
{
if(snapshot.connectionState == ConnectionState.waiting)
{
return Center(
child:Text("Loading")
);
}
else if(snapshot.connectionState == ConnectionState.done)
{
return ListView.builder(itemCount: snapshot.data.length,itemBuilder:(_, index)
{
return Container(
child: ListTile(
title: Text(snapshot.data[index].data()["name"].toString()),
subtitle: Text(snapshot.data[index].data()["price"].toString()),
),
);
});
}
},
),
);
}
}
```![enter image description here](https://i.stack.imgur.com/L7FqF.jpg)
Define your database call as,
Future getStuff() async {
var docs;
await FirebaseFirestore.instance
.collection("buses")
.get()
.then((querySnapshot) {
docs = querySnapshot.docs;
});
return docs;
}
Then use the FutureBuilder in the build() function as,
return Scaffold(
body: Center(
child: FutureBuilder<dynamic>(
future: getStuff(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return Container(
child: ListTile(
title: Text(
snapshot.data[index].data()["name"].toString()),
subtitle: Text(
snapshot.data[index].data()["price"].toString()),
),
);
});
} else {
return CircularProgressIndicator();
}
},
),
),
);
I wrapped the FutureBuilder inside a Center just for clarity, you may remove that Center widget.

using two async call in flutter only one resolved

I am new to flutter and I'm trying to get weather data with two futures but only one is resolved.
I have two async methods getCurrentWeather and getForecasts and getCurrentWeather is not resolve but if I remove getForecasts then getCurrentWeather future is resloved.
What do I miss?
class _YellowBirdState extends State<YellowBird> {
// Future<List<Weather>> weatherField;
Future<Weather> weatherFuture;
Future<List<Weather>> getForecasts() async {
List<Weather> forecasts = await weatherStation.fiveDayForecast();
return forecasts;
}
Future<Weather> getCurrentWeather() async {
Weather current = await weatherStation.currentWeather();
return current;
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: FutureBuilder<Weather>(
future: getCurrentWeather(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.country);
}
return Text('Loading');
})),
Expanded(
child: FutureBuilder<List<Weather>>(
future: getForecasts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Weather> weathers = snapshot.data ?? [];
return ListView.builder(
itemCount: weathers.length,
itemBuilder: (context, index) {
Weather weather = weathers[index];
return ListTile(
leading: Text('aaaa'),
title: new Text(weather.weatherDescription),
onTap: () {},
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
}
// color: const Color(0xFFFFE306)
),
),
],
),
));
}
}