Reputation: 127
I've seen similar questions that were asked in regards to this but my problem is a little different in that I'm keeping my application modular so I have defined the following method in a different dart file(Simply a class, not a widget):
Future getProfile() async {
return await usersCollection.doc(uid).get().then<dynamic>((DocumentSnapshot snapshot) async {
print(snapshot.data()['name']);
if(snapshot.data()['name'] == null){
print("No name exists");
}
else {
return snapshot.data()['name'];
}
});
And I'm trying to use it's value on my home widget:
import 'package:flutter/material.dart';
import 'package:carpoolapp/services/auth.dart';
import 'package:carpoolapp/services/database.dart';
import 'package:firebase_auth/firebase_auth.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final AuthService _auth = AuthService();
User user = FirebaseAuth.instance.currentUser;
DatabaseService db = DatabaseService(uid: FirebaseAuth.instance.currentUser.uid);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.redAccent,
appBar: AppBar(
title: Text('Signed in'),
backgroundColor: Colors.blueAccent,
elevation: 0.0, //no drop shadow
actions: <Widget>[
FlatButton.icon(
onPressed: () async {
await _auth.signOutUser();
},
icon: Icon(Icons.person),
label: Text('logout')),
],
),
body: Text(db.getProfile()), // Error is here
//body: UserTile(user: FirebaseAuth.instance().getCurrentUser()),
);
}
}
How do I go about making this work without sacrificing the modularity?
Upvotes: 5
Views: 32553
Reputation: 25140
I would like to add to @Pradyot Prakash's answer with some actual code:
Use the following code snippet as an example to achieve the modularity
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
future: getProfile() // 👈 Your future function here
builder: (_, snapshot) {
if (snapshot.hasError) return Text('Error = ${snapshot.error}');
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("Loading");
}
Map<String, dynamic> data = snapshot.data!.data()!;
return Text(data['name']); //👈 Your valid data here
},
)),
);
}
Upvotes: 1
Reputation: 136
By seeing
The argument type 'Future<dynamic>' can't be assigned to the parameter type 'String'
this and
Text(db.getProfile())
the issue is db.getProfile()
is an async
method. That's why its telling Future can't be assigned to String
since Text widget data key is of type String
not Future<String>
.
You can use FutureBuilder
in the body and use the snapshot in the Text which will have the String
value.
Upvotes: 12