I had this error of
I/flutter (12204): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (12204): The following NoSuchMethodError was thrown building FutureBuilder<Map<String, dynamic>>(dirty,
I/flutter (12204): dependencies: [Provider], state: _FutureBuilderState<Map<String, dynamic>>#0ec0c):
I/flutter (12204): Class '_InternalLinkedHashMap<String, dynamic>' has no instance getter 'uid'.
I/flutter (12204): Receiver: _LinkedHashMap len:3
I/flutter (12204): Tried calling: uid
I/flutter (12204):
I/flutter (12204): The relevant error-causing widget was:
I/flutter (12204): FutureBuilder<Map<String, dynamic>> file:///D:/Projects/Davrick/curtain/lib/main.dart:26:15
when I run my app. It's a social media app so I need to get the user id when users login and use them for other things (like showing their pictures and messages, so on). First I built this app using Firebase (which was easy)). Now that I am using Django REST framework I am getting some errors.
Below is my code for main.dart:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider(
child: MaterialApp(
title: 'Curtain App',
home: FutureBuilder(
future: AuthService.getToken(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Container();
}
if (snapshot.hasData) {
Provider.of<UserData>(context).currentUserId = snapshot.data.uid; //this line is giving error
return HomeScreen();
} else {
return LoginScreen();
}
},
),
routes: {
LoginScreen.id: (context) => LoginScreen(),
SignupScreen.id: (context) => SignupScreen(),
FeedScreen.id: (context) => FeedScreen(),
},
),
);
}
}
This is the code of AuthService class
static Future<dynamic> loginUser(String username, String password) async {
print(username);
print(password);
final result = await http.post('$baseURL/en/users/login/', headers: {
'Accept': 'application/json',
}, body: {
'username': username,
'password': password,
});
return result?.body;
}
static setToken(String token, String refreshToken) async {
_AuthData data = _AuthData(token, refreshToken);
await SESSION.set('tokens', data);
}
static Future<Map<String, dynamic>> getToken() async {
return await SESSION.get('tokens');
}
static removeToken() async {
await SESSION.prefs.clear();
}
Here is the _AuthData class
class _AuthData {
String token, refreshToken;
_AuthData(this.token, this.refreshToken);
// toJson
// required by Session lib
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['token'] = token;
data['refreshToken'] = refreshToken;
return data;
}
}
I also need to mention that my Provider class is custom made. Kindly help solve this issue. Thank you.
You are retrieving Map<String, dynamic>
from Future
and this class not contains uid
field. You should parse response from the server by way that similar to this:
static Future<String> getToken() async {
// Parse auth data that you needs here and return token only
}
And in FutureBuilder
(I'm added CircularProgressIndicator
when it's better to show to a user something loading widget rather than empty Container
):
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
if (snapshot.hasData) {
Provider.of<UserData>(context).currentUserId = snapshot.data;
return HomeScreen();
} else {
return LoginScreen();
}