Flutter Firebase Google Войти не работает. Останавливается после выбора аккаунта - PullRequest
4 голосов
/ 17 января 2020

В настоящее время я пытаюсь реализовать вход в Google и аутентификацию в моем приложении. Я настроил проект и создал приложение в Firebase, поместил в приложение google-services. json, добавил необходимый плагин для build.gradle и установил ключ SHA-1 в firebase. Аутентификация электронной почты работает отлично, однако аутентификация Google вызывает проблемы.

Вся аутентификация выполняется из пакета «аутентификации», который я создал. Он содержит страницу аутентификации и выполняет все аутентификационные логи c. Запущенное приложение 'main' flutter импортирует этот пакет для использования. Файлы build.gradle этого «основного» проекта содержат дополнения для плагина служб Google (com.google.gms:google-services:4.3.2). Как только основной проект запущен, он проверяет, вошел ли пользователь в данный момент. Если нет, он передает управление пакету аутентификации для отображения экрана аутентификации и обработки входа в систему.

Проблема возникает после выбора учетная запись Google, с которой я хочу войти. После выбора учетной записи диалоговое окно выбора учетной записи закрывается, и после этого ничего не происходит. Пользователь не аутентифицирован (подтверждено в Firebase), не выдается никаких исключений, и триггер-ловушка, окружающая все, не перехватывает никаких исключений. Кажется, что все выполнение функции останавливается. Я все еще могу перемещаться по приложению, но метод входа никогда не заканчивает выполнение.

Вы можете увидеть метод входа ниже. После выполнения строки final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn(); выполнение по какой-то причине не продолжается.

///
  Future<String> _signUpWithGoogle() async {
    bool isLoggedIn = await _firebaseAuth.isLoggedIn();
    if (!isLoggedIn) {
      googleSignIn = GoogleSignIn();
      final GoogleSignInAccount googleSignInAccount =
          await googleSignIn.signIn();
      final GoogleSignInAuthentication googleSignInAuthentication =
          await googleSignInAccount.authentication;

      final AuthCredential credential = GoogleAuthProvider.getCredential(
        accessToken: googleSignInAuthentication.accessToken,
        idToken: googleSignInAuthentication.idToken,
      );

      final AuthResult authResult =
          await _firebaseAuth.signInWithCredential(credential);
      final FirebaseUser user = authResult.user;

      assert(!user.isAnonymous);
      assert(await user.getIdToken() != null);

      final FirebaseUser currentUser = await _firebaseAuth.getUser();
      assert(user.uid == currentUser.uid);

      return 'signInWithGoogle succeeded: $user';
    } else {
      FirebaseUser user = await _firebaseAuth.getUser();
      return 'signInWithGoogle succeeded: $user';
    }
  }

Я бы подумал, что PlatformException должен вернуться, если что-то пошло не так, но в первый раз никакие исключения не возвращаются. Если я снова активирую метод входа в Google, я получаю исключение PlatformException, которое говорит:

PlatformException(error, Concurrent operations detected: signIn, signIn, null)

Ниже вы также можете найти зависимости для «основного» приложения и пакета «аутентификации»:

зависимости «основного» приложения

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2
  permission:
  intl_translation:
  flutter_svg:
  sqflite:
  path:
  path_provider:
  uuid:
  qr_flutter:
  vibration:
  reflectable:
  provider:
  launcher_module:
    path: ../modules/launcher_module
  individual:
    path: ../modules/individual
  common:
    path: ../packages/common
  persistence:
    path: ../packages/persistence
  resources:
    path: ../packages/resources
  authentication:
    path: ../packages/authentication
  screen:
  flutter_screen_scaler: ^0.0.1
  page_indicator:
  toast: ^0.1.5
  rxbus: ^0.0.2
  shared_preferences:

зависимости пакета «аутентификации»

dependencies:
  flutter:
    sdk: flutter
  firebase_auth: ^0.15.3+1
  google_sign_in: ^4.1.1
  flutter_facebook_login:
  shared_preferences:
  common: 
    path: "../common"
  toast: ^0.1.5

Я также попытался переместить все логи аутентификации c в основное приложение и удалил ссылку на пакет «аутентификация». Тем не менее, происходит то же самое.

Есть ли что-то, что я делаю неправильно или отсутствует во всем этом?

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Просто чтобы превратить мой предыдущий комментарий в официальный ответ:

Первоначальный комментарий:

Кажется, с кодом выше все в порядке. У меня есть почти идентичный код, который работает, с той же версией google_sign_in plugin. Что я хотел бы сделать, это отладить собственный код плагина, чтобы выяснить, где он застрял, а затем понять, почему это происходит. Учитывая упомянутое вами PlatformException, и после быстрого взгляда на код плагина, он определенно застревает где-то между обратным вызовом onActivityResult при выборе учетной записи для входа и отправке результата обратно во Flutter.

После того, как автор ответил:

Получается, что автор настроил запуск приложения так, что onActivityResult больше не вызывал super.onActivityResult, что помешало google_sign_in плагин для отправки данных с нативной стороны обратно на сторону флаттера.

Этот же механизм используется всякий раз, когда запускается Intent, предназначенный для возврата данных, например, запрашивая разрешения или фотографируя с другое приложение.

0 голосов
/ 22 января 2020

auth.dart

import 'dart:io';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';

abstract class BaseAuth {

  Future<String> signInWithGoogle();

//optional if you need to store user data
  String name = "User";
  String email = "Demo";
  String imageUrl = "https://celebritypets.net/wp-content/uploads/2016/12/Adriana-Lima.jpg";


}
enum authProblems { UserNotFound, PasswordNotValid, NetworkError }

class Auth implements BaseAuth {

final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();

  Future<String> signInWithGoogle() async {


  final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
  final GoogleSignInAuthentication googleSignInAuthentication =
      await googleSignInAccount.authentication;

  final AuthCredential credential = GoogleAuthProvider.getCredential(
    accessToken: googleSignInAuthentication.accessToken,
    idToken: googleSignInAuthentication.idToken,
  );

  final AuthResult authResult = await _firebaseAuth.signInWithCredential(credential);
  final FirebaseUser user = authResult.user;

  // Checking if email and name is null
  assert(user.email != null);
  assert(user.displayName != null);
  assert(user.photoUrl != null);

  name = user.displayName;
  email = user.email;
  imageUrl = user.photoUrl;


  // Only taking the first part of the name, i.e., First Name
  if (name.contains(" ")) {
    name = name.substring(0, name.indexOf(" "));
  }

  assert(!user.isAnonymous);
  assert(await user.getIdToken() != null);

  final FirebaseUser currentUser = await _firebaseAuth.currentUser();
  assert(user.uid == currentUser.uid);

  return 'signInWithGoogle succeeded: $user';
}

authprovider.dart

import 'package:flutter/material.dart';
import 'package:multitask_flutter/auth.dart';

class AuthProvider extends InheritedWidget {

  AuthProvider({Key key,Widget child, this.auth}) : super(key: key,child: child);
  final BaseAuth auth;


  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;

  static AuthProvider of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<AuthProvider>();
  }

}

loginpage.dart

import 'package:appname_flutter/authprovider.dart';
//just call this... when user click on button...

var auth = AuthProvider.of(context).auth;
auth.handleSignIn();

И вы сделали ...

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...