#flutter #authentication #dart #google-signin
Вопрос:
Я использую Cubit в своем приложении и хочу войти в систему с помощью Google. Я пишу коды, которые приведены ниже, но это приводит к ошибке: Необработанное исключение: noSuchMethod Ошибка: Метод «Вход» был вызван при нуле.
Как я могу это решить? В чем проблема?
Widget googleSignInButton() {
return BlocBuilder<GoogleSignInCubit, GoogleSignInState>(
builder: (context, state) {
return Container(
padding: EdgeInsets.all(4),
child: OutlinedButton.icon(
label: Text(
'Sign In With Google',
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
),
icon: FaIcon(FontAwesomeIcons.google, color: Colors.red),
onPressed: () {
BlocProvider.of<GoogleSignInCubit>(context).signInWithGoogle();
},
),
);
});
}
.
окончательный gSignIn = жду GoogleSignIn.вход(); >>>>>>>>>>>>>>> Я думаю, что проблема здесь..
class GoogleSignInCubit extends Cubit<GoogleSignInState> {
GoogleSignIn googleSignIn;
bool isSignIn = false;
GoogleSignInCubit() : super(GoogleSignInState.initial());
Future signInWithGoogle() async {
final gSignIn = await googleSignIn.signIn();
if (gSignIn == null) {
return null;
} else {
final googleAuth = await gSignIn.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
final uid = FirebaseAuth.instance.currentUser.uid;
final existingUserDocs = await FirebaseFirestore.instance
.collection('Users')
.where('uid', isEqualTo: gSignIn.id)
.get();
if (existingUserDocs.docs.isEmpty) {
FirebaseFirestore.instance.collection('Users').doc(uid).set({
'email': gSignIn.email,
'username': gSignIn.displayName,
'uid': uid,
'userPhotoUrl': gSignIn.photoUrl
});
}
isSignIn = true;
emit(GoogleSignInState.success(isSignIn));
}
}
Future<void> logout() async {
await googleSignIn.disconnect();
FirebaseAuth.instance.signOut();
}
}
.
abstract class GoogleSignInState with _$GoogleSignInState {
const factory GoogleSignInState({@required bool isSignIn}) = _GoogleSignInState;
factory GoogleSignInState.initial() => GoogleSignInState(isSignIn: false);
factory GoogleSignInState.failure(String failureMsg) = _Failure;
factory GoogleSignInState.success(bool isSuccess) = _Success;
}
Комментарии:
1. я также использую замороженный, но я думаю, что это не имеет значения
Ответ №1:
Вы забыли инициализировать вход в Google. Вы можете инициализировать следующим образом:
GoogleSignInCubit({@required this.googleSignIn}) :
super(GoogleSignInState.initial());
Конечно, вам придется пройти вход в Google, когда вы создадите cubit.
BlocProvider<GoogleSignInCubit>(
create: (context) {
return GoogleSignInCubit(googleSignIn: GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
),
}
)
Другой способ инициализации (который я бы предпочел в этой ситуации) — сделать переменную GoogleSignIn закрытой, изменив ее на _googleSignIn. Затем:
class GoogleSignInCubit extends Cubit<GoogleSignInState> {
GoogleSignIn _googleSignIn;
bool isSignIn = false;
GoogleSignInCubit({GoogleSignIn googleSignIn}) :
_googleSignIn = googleSignIn ?? GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
), super(GoogleSignInState.initial());
Future signInWithGoogle() async {
Комментарии:
1. тип «GoogleSignInCubit» не является подтипом типа «GoogleSignIn», он выдает эту ошибку
2. также я использовал код, который приведен ниже в строке «Вы забыли», он работал, но я не понимаю других кодов. Например, вы упомянули, что «Я ПРЕДПОЧИТАЮ», и это не сработало, и я не понял, можете ли вы объяснить
3. Я отредактировал свой ответ, чтобы устранить проблему. Хотя первый должен был сработать.