在 null 上调用了 getter 'keys'

Posted

技术标签:

【中文标题】在 null 上调用了 getter \'keys\'【英文标题】:The getter 'keys' was called on null在 null 上调用了 getter 'keys' 【发布时间】:2020-10-24 05:20:49 【问题描述】:

我还不明白这个框架,你能帮忙解决这个错误吗?我正在尝试获取基本的用户数据 enter image description here

扑扑医生:

[!] android 工具链 - 为 Android 设备开发(Android SDK 版本 30.0.0) !不接受某些 Android 许可证。要解决此问题,请运行: 颤振医生 --android-licenses [!] Android Studio (4.0 版) X Flutter 插件未安装;这增加了 Flutter 特定的 功能。 X Dart 插件未安装;这增加了 Dart 特定的 功能。 [√] 已连接设备(1 个可用)

!医生发现了 2 类问题。

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'constants.dart';
import 'package:simple_auth/simple_auth.dart' as simpleAuth;
import 'package:simple_auth_flutter/simple_auth_flutter.dart';


class Inst_Login extends StatefulWidget 
  Inst_Login(Key key) : super(key: key);

  @override
  _Inst_LoginState createState() => _Inst_LoginState();


class _Inst_LoginState extends State<Inst_Login> 
  String _errorMsg;
  Map _userData;

  final simpleAuth.InstagramApi _igApi = simpleAuth.InstagramApi(
    "instagram",
    Constants.igClientId,
    Constants.igClientSecret,
    Constants.igRedirectURL,
    scopes: [
      'user_profile', // For getting username, account type, etc.
      'user_media', // For accessing media count & data like posts, videos etc.
    ],
  );

  @override
  void initState() 
    super.initState();
    SimpleAuthFlutter.init(context);
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('Instagram Basic Display API Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Visibility(
              visible: _userData != null,
              child: Text(
                _userData.keys.fold(
                    '', (kvText, key) => kvText + "$key: $_userData[key] \n"),
                textAlign: TextAlign.center,
              ),
              replacement:
              Text("Click the button below to get Instagram Login."),
            ),
            FlatButton.icon(
              icon: Icon(Icons.input),
              label: Text(
                "Get Profile Data",
              ),
              onPressed: _loginAndGetData,
              color: Colors.pink.shade400,
            ),
            if (_errorMsg != null) Text("Error occured: $_errorMsg"),
          ],
        ),
      ),
    );
  

  Future<void> _loginAndGetData() async 
    _igApi.authenticate().then(
          (simpleAuth.Account _user) async 
        simpleAuth.OAuthAccount user = _user;

        var igUserResponse =
        await Dio(BaseOptions(baseUrl: 'https://graph.instagram.com')).get(
          '/me',
          queryParameters: 
            // Get the fields you need.
            // https://developers.facebook.com/docs/instagram-basic-display-api/reference/user
            "fields": "username,id,account_type,media_count",
            "access_token": user.token,
          ,
        );

        setState(() 
          _userData = igUserResponse.data;
          _errorMsg = null;
        );
      ,
    ).catchError(
          (Object e) 
        setState(() => _errorMsg = e.toString());
      ,
    );
  

【问题讨论】:

【参考方案1】:

即使您使用的是Visibility widget,如果您正在执行 API 调用(即 async 并返回 Future,那么小部件也不应该有 null _userdata,然后使用 FutureBuilder

FutureBuilder 的代码将是 -

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'constants.dart';
import 'package:simple_auth/simple_auth.dart' as simpleAuth;
import 'package:simple_auth_flutter/simple_auth_flutter.dart';

class Inst_Login extends StatefulWidget 
  Inst_Login(Key key) : super(key: key);

  @override
  _Inst_LoginState createState() => _Inst_LoginState();


class _Inst_LoginState extends State<Inst_Login> 
  String _errorMsg;
  Map _userData;

  final simpleAuth.InstagramApi _igApi = simpleAuth.InstagramApi(
    "instagram",
    Constants.igClientId,
    Constants.igClientSecret,
    Constants.igRedirectURL,
    scopes: [
      'user_profile', // For getting username, account type, etc.
      'user_media', // For accessing media count & data like posts, videos etc.
    ],
  );

  @override
  void initState() 
    super.initState();
    SimpleAuthFlutter.init(context);
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('Instagram Basic Display API Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FutureBuilder(
              future: _loginAndGetData(),
              builder: (context, snapshot) 
                if (snapshot.connectionState == ConnectionState.done)
                  return Text(
                    _userData.keys.fold('',
                        (kvText, key) => kvText + "$key: $_userData[key] \n"),
                    textAlign: TextAlign.center,
                  );
                return Text("Click the button below to get Instagram Login.");
              ,
            ),
            FlatButton.icon(
              icon: Icon(Icons.input),
              label: Text(
                "Get Profile Data",
              ),
              onPressed: _loginAndGetData,
              color: Colors.pink.shade400,
            ),
            if (_errorMsg != null) Text("Error occured: $_errorMsg"),
          ],
        ),
      ),
    );
  

  Future<void> _loginAndGetData() async 
    _igApi.authenticate().then(
      (simpleAuth.Account _user) async 
        simpleAuth.OAuthAccount user = _user;

        var igUserResponse =
            await Dio(BaseOptions(baseUrl: 'https://graph.instagram.com')).get(
          '/me',
          queryParameters: 
            // Get the fields you need.
            // https://developers.facebook.com/docs/instagram-basic-display-api/reference/user
            "fields": "username,id,account_type,media_count",
            "access_token": user.token,
          ,
        );

        setState(() 
          _userData = igUserResponse.data;
          _errorMsg = null;
        );
      ,
    ).catchError(
      (Object e) 
        setState(() => _errorMsg = e.toString());
      ,
    );
  

如果您在评论中提出任何问题或问题,希望这会对您有所帮助。

【讨论】:

哦,谢谢!但我对redirectUri 有疑问。这个字段应该包含什么?我可以使用localhost:8585 吗?因为现在我有错误:(无效的redirect_uri)当我把localhost 您将在您的 facebook 开发者面板中找到重定向身份验证 url。 是的,但是我如何在身份验证后将 uri 添加到我的应用程序中? 我不明白你想在应用程序中返回什么。 我想在认证后返回我的应用程序,我不知道该怎么做

以上是关于在 null 上调用了 getter 'keys'的主要内容,如果未能解决你的问题,请参考以下文章

在 null 上调用了 getter 'user'

例外:NoSuchMethodError:在 null 上调用了 getter 'uid'。接收方:null 尝试调用:uid

错误“在 null 上调用了 getter 'userEmail'

在 null 上调用了 getter '_controller'。扑

如何修复“在 null 上调用了 getter “文档”。飘飘然

发布 http 请求:在 null 颤动上调用了 getter 'length'