Flutter _googleSignIn.signizenly()不起作用

Flutter _googleSignIn.signizenly()不起作用,flutter,google-signin,Flutter,Google Signin,我已经从中复制粘贴了整个代码,但仍然在_googleSignIn.signizenley()上出现以下错误 请查看下面提到的main.dart文件的代码段 // Copyright 2019 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // igno

我已经从中复制粘贴了整个代码,但仍然在_googleSignIn.signizenley()上出现以下错误

请查看下面提到的main.dart文件的代码段

// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'dart:async';
import 'dart:convert' show json;

import "package:http/http.dart" as http;
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';

GoogleSignIn _googleSignIn = GoogleSignIn(
  scopes: <String>[
    'email',
    'https://www.googleapis.com/auth/contacts.readonly',
  ],
);

void main() {
  runApp(
    MaterialApp(
      title: 'Google Sign In',
      home: SignInDemo(),
    ),
  );
}

class SignInDemo extends StatefulWidget {
  @override
  State createState() => SignInDemoState();
}

class SignInDemoState extends State<SignInDemo> {
  GoogleSignInAccount _currentUser;
  String _contactText;

  @override
  void initState() {
    super.initState();
    _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account) {
      setState(() {
        _currentUser = account;
      });
      if (_currentUser != null) {
        _handleGetContact();
      }
    });
    _googleSignIn.signInSilently();
  }

  Future<void> _handleGetContact() async {
    setState(() {
      _contactText = "Loading contact info...";
    });
    final http.Response response = await http.get(
      'https://people.googleapis.com/v1/people/me/connections'
      '?requestMask.includeField=person.names',
      headers: await _currentUser.authHeaders,
    );
    if (response.statusCode != 200) {
      setState(() {
        _contactText = "People API gave a ${response.statusCode} "
            "response. Check logs for details.";
      });
      print('People API ${response.statusCode} response: ${response.body}');
      return;
    }
    final Map<String, dynamic> data = json.decode(response.body);
    final String namedContact = _pickFirstNamedContact(data);
    setState(() {
      if (namedContact != null) {
        _contactText = "I see you know $namedContact!";
      } else {
        _contactText = "No contacts to display.";
      }
    });
  }

  String _pickFirstNamedContact(Map<String, dynamic> data) {
    final List<dynamic> connections = data['connections'];
    final Map<String, dynamic> contact = connections?.firstWhere(
      (dynamic contact) => contact['names'] != null,
      orElse: () => null,
    );
    if (contact != null) {
      final Map<String, dynamic> name = contact['names'].firstWhere(
        (dynamic name) => name['displayName'] != null,
        orElse: () => null,
      );
      if (name != null) {
        return name['displayName'];
      }
    }
    return null;
  }

  Future<void> _handleSignIn() async {
    try {
      await _googleSignIn.signIn();
    } catch (error) {
      print(error);
    }
  }

  Future<void> _handleSignOut() => _googleSignIn.disconnect();

  Widget _buildBody() {
    if (_currentUser != null) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          ListTile(
            leading: GoogleUserCircleAvatar(
              identity: _currentUser,
            ),
            title: Text(_currentUser.displayName ?? ''),
            subtitle: Text(_currentUser.email ?? ''),
          ),
          const Text("Signed in successfully."),
          Text(_contactText ?? ''),
          RaisedButton(
            child: const Text('SIGN OUT'),
            onPressed: _handleSignOut,
          ),
          RaisedButton(
            child: const Text('REFRESH'),
            onPressed: _handleGetContact,
          ),
        ],
      );
    } else {
      return Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          const Text("You are not currently signed in."),
          RaisedButton(
            child: const Text('SIGN IN'),
            onPressed: _handleSignIn,
          ),
        ],
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Google Sign In'),
        ),
        body: ConstrainedBox(
          constraints: const BoxConstraints.expand(),
          child: _buildBody(),
        ));
  }
}
//颤振作者版权所有。版权所有。
//此源代码的使用受BSD样式许可证的约束,该许可证可以
//在许可证文件中找到。
//忽略\u文件的\u:公共\u成员\u api\u文档
导入“dart:async”;
导入“dart:convert”显示json;
将“package:http/http.dart”导入为http;
进口“包装:颤振/材料.省道”;
导入“包:google_sign_in/google_sign_in.dart”;
谷歌签名(
范围:[
“电子邮件”,
'https://www.googleapis.com/auth/contacts.readonly',
],
);
void main(){
runApp(
材料聚丙烯(
标题:“谷歌登录”,
主页:SignInDemo(),
),
);
}
类SignInDemo扩展StatefulWidget{
@凌驾
状态createState()=>SignInDemoState();
}
类SignInDemoState扩展状态{
GoogleSignInAccount\u currentUser;
字符串_contactText;
@凌驾
void initState(){
super.initState();
_googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount帐户){
设置状态(){
_当前用户=帐户;
});
如果(_currentUser!=null){
_handleGetContact();
}
});
_googleSignIn.signizely();
}
Future _handleGetContact()异步{
设置状态(){
_contactText=“正在加载联系人信息…”;
});
final http.Response Response=wait http.get(
'https://people.googleapis.com/v1/people/me/connections'
“?requestMask.includeField=person.names”,
headers:await\u currentUser.authHeaders,
);
如果(response.statusCode!=200){
设置状态(){
_contactText=“People API提供了${response.statusCode}”
“响应。有关详细信息,请查看日志。”;
});
打印('People API${response.statusCode}响应:${response.body}');
返回;
}
最终映射数据=json.decode(response.body);
最终字符串namedContact=\u pickFirstNamedContact(数据);
设置状态(){
if(namedContact!=null){
_contactText=“我知道你知道$namedContact!”;
}否则{
_contactText=“没有要显示的联系人。”;
}
});
}
字符串\u pickFirstNamedContact(地图数据){
最终列表连接=数据[‘连接’];
最终地图联系人=连接?.firstWhere(
(动态联系人)=>联系人['names'!=null,
orElse:()=>null,
);
如果(联系人!=null){
最终地图名称=联系人['names']。firstWhere(
(动态名称)=>name['displayName']!=null,
orElse:()=>null,
);
if(name!=null){
返回名称['displayName'];
}
}
返回null;
}
Future\u handleSignIn()异步{
试一试{
等待谷歌签名;
}捕获(错误){
打印(错误);
}
}
Future _handleSignOut()=>_googleSignIn.disconnect();
小部件_buildBody(){
如果(_currentUser!=null){
返回列(
mainAxisAlignment:mainAxisAlignment.spaceAround,
儿童:[
列表砖(
领先:谷歌用户Circleavatar(
标识:_当前用户,
),
标题:文本(_currentUser.displayName??“”),
字幕:文本(_currentUser.email??“”),
),
const Text(“已成功登录”),
文本(_contactText??“”),
升起的按钮(
子项:常量文本(“注销”),
按下按钮:_handleSignOut,
),
升起的按钮(
子项:常量文本(“刷新”),
按下按钮:_handleGetContact,
),
],
);
}否则{
返回列(
mainAxisAlignment:mainAxisAlignment.spaceAround,
儿童:[
const Text(“您当前未登录。”),
升起的按钮(
子项:常量文本(“登录”),
按下按钮:_handleSignIn,
),
],
);
}
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:const Text(“谷歌登录”),
),
主体:约束框(
约束:const-BoxConstraints.expand(),
子项:_buildBody(),
));
}
}
我想使用firebase作为我的后端。但在这样做之前,这对我来说是行不通的


我可以看到:这里他们也在使用相同的技术。

这个错误意味着密钥链中没有身份验证令牌,我曾经面对过它并解决了这个问题,我复制并发送了我在下面使用的代码,您也可以从该线程检查其他解决方案

if GIDSignIn.sharedInstance().hasAuthInKeychain() == true{
    GIDSignIn.sharedInstance().signInSilently()
}
else{
    GIDSignIn.sharedInstance().signIn()
}

根据包装要求:

要访问Google登录,您需要确保(向firebase)注册您的应用程序

你不需要在你的应用程序中包含google-services.json文件,除非你正在使用需要它的谷歌服务。您确实需要使用Google云平台API管理器启用所需的OAuth API。例如,如果您想要模拟Google登录示例应用程序的行为,则需要启用Google People API

确保在控制台中填写了OAuth同意屏幕的所有必填字段。否则,您可能会遇到异常错误


是的,我已经完成了,并且完成了所有的要求。我已经在演示应用程序上进行了测试,样本工作顺利,没有任何问题。您可能需要确保1。您已向firebase 2注册应用程序。您已经在google控制台上为同一项目启用了people api。3.您已将人员api联系人范围添加到oauth同意屏幕。4.你可以第一次登录5。应用程序请求权限6。你同意一切。7.它第一次显示当前登录的用户。8.重新启动应用程序应该能够以静默方式登录。
if GIDSignIn.sharedInstance().hasAuthInKeychain() == true{
    GIDSignIn.sharedInstance().signInSilently()
}
else{
    GIDSignIn.sharedInstance().signIn()
}