How to solve Class '_InternalLinkedHashMap<String, dynamic>' has no instance getter 'uid'

Issue

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.

Solution

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();
}

Answered By – fartem

Answer Checked By – Marie Seifert (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *