return a bool value from a Future<bool> function in flutter

64 views Asked by At

My Question is a bit similar to How can I get my bool value out of a future<bool>? but i couldn't get an aswer to my question from it. I have the function in a seperate file because i also want to use it elsewhere in my code. I am trying to create a function that checks if the current user is the creator of the document. For that i use an async method in my function so it has to be Future but if I run my App i get this error: wrong return type error

The field userId in my Database is defined and saves the userId of the Author when it is created.

this is the function:

 Future<bool> isUserAuthor(documentId) async {
      var userId = '';
      String? currentUserId = FirebaseAuth.instance.currentUser?.uid;
      var collection = FirebaseFirestore.instance.collection('notes');
      var docSnapshot = await collection.doc(documentId).get();
      if (docSnapshot.exists) {
        userId = docSnapshot.data()?['userId'];
      } else {
        userId = 'no User available';
      }
      if (userId == currentUserId) {
        return true;
      } else {
        return false;
      }
    }

and this is where i use it:

 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);
            },
            title: Text(
              note.textJob,
              maxLines: 1,
              softWrap: true,
              overflow: TextOverflow.ellipsis,
            ),
            trailing: FutureBuilder(
                future: isUserAuthor(note.documentId),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    bool isvisible = snapshot.data as bool;
                    print(isvisible);
                    return Visibility(
                      visible: isvisible,
                      child: IconButton(
                        onPressed: () async {
                          final shouldDelete = await showDeleteDialog(context);
                          if (shouldDelete) {
                            (note);
                          }
                        },
                        icon: const Icon(Icons.delete),
                      ),
                    );
                  } else if (snapshot.hasError) {
                    return const CircularProgressIndicator.adaptive(
                      backgroundColor: Colors.amber,
                    );
                  } else {
                    return const CircularProgressIndicator();
                  }
                }));
      },
    );
  }
}

If you have any other questiones to the rest of my code please write me. I don't programm very long and for that don't know what else you would need.

3

There are 3 answers

0
JustYousefSameh On

In cases like this you need to use a FutureBuilder

here is a link: https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

0
Vandan Patel On

Save the response of the isUserAuthor function in boolean variable and then use it. Also call isUserAuthor function before the execution of ListView.builder.

5
A-E On

I think that line is the source of the error

bool isvisible = isUserAuthor(note.documentId) as bool;

isUserAuthor() , is an asynchronous function the returns a boolean value in the future.

So, you should wait for it to get the complete result, eg:

bool isvisible = await isUserAuthor(note.documentId) ;

and of course you must mark your function (itemBuilder) as asynchronous. which is not allowed.

Fix:

Wrap the trailing widget of the ListTile with a FutureBuilder

trailing : FutureBuilder(

future: isUserAuthor(note.documentId),
builder:(context,snapshot){
if(snapshot.hasData){

// return  visibillity widget here
}
else if (snapshot.hasError){

// error state
}

// return loading widget
}
)

you can access the returned value of the future by snapshot.data