Future still returns null Flutter - flutter

I have this function that calls a Future<bool> function :
bool checkId(String id, context) {
bool ret;
checkMissingId(id, context).then((value) => ret = value);
return ret;
That calls :
Future<bool> checkMissingId(String id, context) async {
String str = id.toLowerCase();
String letter = str[0];
if (checkStr(id, letter, str) == false)
return false; //checks some rules on strings
else {
try {
var data = await FirebaseFirestore.instance
.collection("ids/tabs/" + letter)
.doc(str)
.get();
if (data.exists) {
return false;
} else
return true;
} catch (e) {
await showErrDialog(context, e.code);
return false;
}
}
}
ret returns null, not a bool value.
Edit : checkId must be of type bool, not Future<bool>

Because it is null when the checkId function returns. You should await the operation, like this:
Future<bool> checkId(String id, context) async {
bool ret = await checkMissingId(id, context);
return ret;
}

You need to pause the execution of the program for the checkMissingId method to complete before return the ret variable. You do this by using the await keyword and marking the function as async.
You should change the code to:
Future<bool> checkId(String id, context) async {
bool ret = await checkMissingId(id, context);
return ret;
}

Related

The return type 'SignUpScreen' isn't a 'void', as required by the closure's context

I'm trying to build a funtion who return Widget for persiting state but I am getting this error.
Future<Widget?> persiting () async {
await FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
return SignUpScreen() ;
} else {
return HomeScreen() ;
}
});
}
try this:
Future<Widget?> persiting () async {
late bool hasUsers;
await FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
hasUsers = true;
} else {
hasUsers = false;
}
});
return hasUsers ? SignUpScreen() : HomeScreen();
}
The exception showed because you are returning onject to the .listen() function instead of the persiting() function.
What you need to do is await to listen the stream inside the presiting() function.
Future<Widget?> persiting () async {
try{
Stream<User?> stream = await FirebaseAuth.instance
.authStateChanges();
bool hasUser = false;
await stream.forEach((user){
hasUser = user != null;
});
return hasUser? HomeScreen() : SignUpScreen();
}catch(e){
/// better do some handling if any network or unexpected error here
}
}

Flutter/Dart convert future bool to bool

Can some one help me to identify the issue in below piece of code
void main() async {
bool c =getstatus();
print(c);
}
Future<bool> getMockData() {
return Future.value(false);
}
bool getstatus() async
{
Future<bool> stringFuture = getMockData();
bool message = stringFuture;
return(message); // will print one on console.
}
To get values from a Future(async) method, you have to await them. And after await the variable you get is not a Future anymore. So basically your code should look like this:
void main() async {
bool c = await getstatus();
print(c);
}
Future<bool> getMockData() {
return Future.value(false);
}
Future<bool> getstatus() async {
bool message = await getMockData();
return message;
}
Future<bool> stringFuture = await getMockData();
an async method must return Future of something then in the main you have to get the bool value by writing await
void main() async {
bool c = await getstatus();
print(c); // will print false on the console.
}
Future<bool> getMockData() {
return Future.value(false);
}
Future<bool> getstatus() async {
Future<bool> stringFuture = await getMockData();
return stringFuture; // will return false.
}

Future<bool> function returns null value flutter

Before posting I took at look at previous questions (because there are many) but I didn't find something that suited my needs.
I have a function that checks if a document exists or not on Firestore, then if the document exists the function must return false, otherwise if not exists, true.
The problem is that the return of the function is always null and also compiler told me that the function doesn't have a return statement but I don't understand why.
This is the code, the important function is checkMissingId the other one just checks if the string id has a valid format or not.
Code :
bool checkStr(String id, String letter, String str) {
if (id.length < 1) {
print("Id is too short");
return false;
} else {
if ('a'.codeUnitAt(0) > letter.codeUnitAt(0) ||
'z'.codeUnitAt(0) < letter.codeUnitAt(0)) {
print("User name begins with bad word!");
return false;
}
print("ids/tabs/" + letter);
return true;
}
}
Future<bool> checkMissingId(String id, context) async {
String str = id.toLowerCase();
String letter = str[0];
if (checkStr(id, letter, str) == false)
return false; //checks some rules on strings
else {
try {
await FirebaseFirestore.instance.collection("ids/tabs/" + letter).doc(str).get()
.then((DocumentSnapshot documentSnapshot) { //Maybe here!(??)
if (documentSnapshot.exists) {
print("Document exists!");
return false;
} else {
print('Document does not exist on the database');
return true;
}
});
} catch (e) {
await showErrDialog(context, e.code);
return false;
}
}
}
The problem is that you are using both await and .then() for getting data from Firestore. Replace your function with this to get desired result:
Future<bool> checkMissingId(String id, context) async {
String str = id.toLowerCase();
String letter = str[0];
if (checkStr(id, letter, str) == false) return false; //checks some rules on strings
else {
try {
DocumentSnapshot documentSnapshot = await FirebaseFirestore.instance.collection("ids/tabs/" + letter).doc(str).get();
if (documentSnapshot.exists) {
print("Document exists!");
return false;
} else {
print('Document does not exist on the database');
return true;
}
} catch (e) {
await showErrDialog(context, e.code);
return false;
}
}
}
Try this:
Future<bool> checkMissingId(String id, context) async {
String str = id.toLowerCase();
String letter = str[0];
if (checkStr(id, letter, str) == false)
return false; //checks some rules on strings
else {
try {
var data = await FirebaseFirestore.instance.collection("ids/tabs/" + letter).doc(str).get()
if (data.exists) {
print("Document exists!");
return false;
} else {
print('Document does not exist on the database');
return true;
}
} catch (e) {
await showErrDialog(context, e.code);
return false;
}
}
}
The problem was that in the .then(...) function, it takes a function as input. So, you wouldn't be able to return anything. Because it doesn't return data to your function.

How to convert Future<bool> into Stream<bool>

In my Flutter app, I have a function returning Future, but I wanna get result as Stream. Here is the function :
Future<bool> isGpsOn() async {
if (await Geolocator().isLocationServiceEnabled()) {
return true;
} else {
return false;
}
}
How to do that?
Read the manual and check my answer:
Stream<bool> gpsStatusStream() async* {
bool enabled;
while (true) {
try {
bool isEnabled = await Geolocator().isLocationServiceEnabled();
if (enabled != isEnabled) {
enabled = isEnabled;
yield enabled;
}
}
catch (error) {}
await Future.delayed(Duration(seconds: 5));
}
}
gpsStatusStream().listen((enabled) {
print(enabled ? 'enabled' : 'disabled');
});
or create convertor:
Stream futureToStream(fn, defaultValue, Duration duration) async* {
var result;
while (true) {
try {
result = await fn();
}
catch (error) {
result = defaultValue;
}
finally {
yield result;
}
await Future.delayed(duration);
}
}
Future<bool> isGpsOn() async {
return await Geolocator().isLocationServiceEnabled();
}
final gpsStatusStream = futureToStream(isGpsOn, false, Duration(seconds: 5));
gpsStatusStream.listen((enabled) {
print(enabled ? 'enabled' : 'disabled');
});
If you don't want to change the return type of your function, you could make callers convert the Future<T> to a Stream<T> by simply calling asStream() on the returned Future.

Can not convert Future data to exact data

I am using Future to return some information from Firebase database that return Future .Now i wanted to convert bool.Here i am faceting null .But into the then function i found my value but when i return it its remain null.
Future<bool> _isfav(String post_key) async {
bool _is_fav;
await FirebaseDatabase.instance
.reference()
.child(Common.user)
.child(Common.number)
.child("favourite")
.child(post_key)
.once()
.then((v) {
print(v.value);
if (v.value != null) {
_is_fav = true;
} else {
_is_fav= false;
}
}).catchError((err) => print(err));
return _is_fav; }
This code perfectly fine .But now
bool read_fav(String index) {
bool data;
_isfav(index).then((v){
data= v;
print(data); /// printing data
});
print(data); //printing null
return data; //returning null }
When i print data into the then function its show my data but when i return it its return null.
i wanted calling the function from here
child: Icon(
Icons.favorite,
color:read_fav(_key[index])!=null && read_fav(_key[index]) == true
? Colors.blue
: Colors.black,
)),
Just follow the code like,
Future<bool> _isfav(String post_key) async {
bool _is_fav;
var snapData = await FirebaseDatabase.instance
.reference()
.child(Common.user)
.child(Common.number)
.child("favourite")
.child(post_key)
.once();
if (v.value != null) {
_is_fav = true;
} else {
_is_fav = false;
}
return _is_fav;
}
Future<bool> read_fav(String index) async{
bool data=false;
data=await _isfav(index);
return data;
}
Also, read_fav will be a future method. because it depends on _isFav() return value which will be predicted in future.
bool isReadFav=await read_fav(index);
Just refer dart await and then concepts at Here
You're all set.