Плагин Amplify Auth для ошибки Flutter «Плагин не добавлен»

Я использую Amplify с Flutter для аутентификации пользователя, но не могу получить сеанс пользователя. Ошибка, которую я получаю:

> Launching lib/main.dart on 2109119DG in debug mode...
Running Gradle task 'assembleDebug'...
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
Debug service listening on ws://xxxx
Syncing files to device 2109119DG...
I/amplify:flutter:auth_cognito(27806): Added Auth plugin
E/flutter (27806): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: AmplifyException(message: Auth plugin has not been added to Amplify, recoverySuggestion: Add Auth plugin to Amplify and call configure before calling Auth related APIs, underlyingException: null)
E/flutter (27806): #0      AuthCategory.fetchAuthSession (package:amplify_core/src/category/amplify_auth_category.dart:189:11)
E/flutter (27806): #1      _MyAppState.isUserSignedIn (package:base_app/main.dart:37:39)
E/flutter (27806): #2      _MyAppState.build (package:base_app/main.dart:47:21)
E/flutter (27806): #3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4992:27)
E/flutter (27806): #4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15)
E/flutter (27806): #5      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5050:11)
E/flutter (27806): #6      Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
E/flutter (27806): #7      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5)
E/flutter (27806): #8      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5041:11)
E/flutter (27806): #9      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
E/flutter (27806): #10     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
E/flutter (27806): #11     Element.updateChild (package:flutter/src/widgets/framework.dart:3592:18)
E/flutter (27806): #12     RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1195:16)
E/flutter (27806): #13     RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1164:5)
E/flutter (27806): #14     RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1111:18)
E/flutter (27806): #15     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2605:19)
E/flutter (27806): #16     RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1110:13)
E/flutter (27806): #17     WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:945:7)
E/flutter (27806): #18     WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:925:7)
E/flutter (27806): #19     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
E/flutter (27806): #20     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
E/flutter (27806): #21     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
E/flutter (27806): #22     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
E/flutter (27806): 
D/AWSMobileClient(27806): Using the SignInProviderConfig from `awsconfiguration.json`.
D/AWSMobileClient(27806): Inspecting user state details
I/flutter (27806): Successfully configured
D/AWSMobileClient(27806): Inspecting user state details
I/TetheringManager(27806): registerTetheringEventCallback:com.dontknow.base_app
D/AWSMobileClient(27806): hasFederatedToken: false provider: cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxx
D/AWSMobileClient(27806): hasFederatedToken: false provider: cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxx
D/AWSMobileClient(27806): Inspecting user state details
D/AWSMobileClient(27806): hasFederatedToken: true provider: cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxx
D/AWSMobileClient(27806): waitForSignIn: userState:SIGNED_IN
D/AWSMobileClient(27806): getCredentials: Validated user is signed-in

Я строго следовал туториалам AWS и добавил плагин перед вызовом «настроить» в коде. Что также странно, так это то, что в строке, предшествующей ошибке, действительно загружается плагин.

Вот мой main.dart:

  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    _configureAmplify();
  }

  void _configureAmplify() async {
    try {
      await Amplify.addPlugin(AmplifyAuthCognito());
      await Amplify.configure(amplifyconfig);
      print('Successfully configured');
    } on Exception catch (e) {
      print('Error configuring Amplify: $e');
    }
  }

  Future<bool> isUserSignedIn() async {
    final result = await Amplify.Auth.fetchAuthSession();
    return result.isSignedIn;
  }

  @override
  Widget build(BuildContext context) {
    return Authenticator(
      child: MaterialApp(
        builder: Authenticator.builder(),
        home: FutureBuilder(
            future: isUserSignedIn(),
            builder: (BuildContext ctx, AsyncSnapshot snapshot) {
              if (snapshot.data == null) {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              } else {
                return Text("logged in");
              }
            }),
      ),
    );
  }
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы пытаетесь выполнить асинхронную работу в initState(), но ее завершение до вызова build() не гарантируется. Поэтому, когда вы вызываете Amplify.Auth.fetchAuthSession() в своей build() функции, инициализация и настройка не завершены.

Попробуйте вызвать _configureAmplify() до runApp().

Чтобы это работало, вам также нужно вызвать WidgetsBinding ensureInitialized() перед _configureAmplify().

Как правило, такая работа не относится к коду пользовательского интерфейса (страницы или виджеты). Скорее это должно быть сделано в управлении состоянием приложения.

Имеет смысл. Поскольку я только что скопировал это из учебника AWS, мне интересно, почему они делают это таким образом, если он не работает должным образом.

Muleque 06.01.2023 11:22

@Muleque Вполне возможно, что это сработало для них, поскольку такие условия гонки дают совершенно непредсказуемые результаты. Может быть очень трудно определить, все ли работает, пока вы не добавите какое-нибудь тривиальное изменение в дерево виджетов.

Ber 06.01.2023 19:45

к сожалению, когда я помещаю _configureAmplify() в main, я получаю еще одну ошибку: [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Binding has not yet been initialized. Я застрял здесь.

Muleque 07.01.2023 09:29

Да. Это потому, что привязки флаттера не были инициализированы в то время. Вам также необходимо вызвать WidgetsBinding.ensureInitialized() перед настройкой Amplify.

Ber 07.01.2023 12:11
Ответ принят как подходящий

Наконец-то я нашел подходящее исправление, соответствующее моему уровню навыков, здесь github-repo

Я добавил переменную состояния _isAmplifyConfigured, которая устанавливается в true, когда _configureAmplify() завершается. Затем в построителе я проверяю, настроено ли усиление или нет, с помощью простого оператора if-else. Вот полный код:

import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_authenticator/amplify_authenticator.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:flutter/material.dart';

import 'amplifyconfiguration.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isAmplifyConfigured = false;

  @override
  void initState() {
    super.initState();
    _configureAmplify();
  }

  void _configureAmplify() async {
    try {
      await Amplify.addPlugin(AmplifyAuthCognito());
      await Amplify.configure(amplifyconfig);
      setState(() => _isAmplifyConfigured = true);
      print('Successfully configured');
    } on Exception catch (e) {
      print('Error configuring Amplify: $e');
    }
  }

  Future<bool> isUserSignedIn() async {
    final result = await Amplify.Auth.fetchAuthSession();
    return result.isSignedIn;
  }

  @override
  Widget build(BuildContext context) {
    return Authenticator(
      child: MaterialApp(
        builder: Authenticator.builder(),
        home: _isAmplifyConfigured? FutureBuilder(
            future: isUserSignedIn(),
            builder: (BuildContext ctx, AsyncSnapshot snapshot) {
              if (snapshot.data == null) {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              } else {
                return Text("logged in");
              }
            }): Text("not logged in")
      ),
    );
  }
}

Другие вопросы по теме

Проверка кода spring boot mfa totp при входе в систему не работает
Могу ли я запустить аутентификацию классической карты Mifare по адресу, хранящемуся в блоке значений?
Как перенаправить пользователя на страницу входа, если срок действия токена истек
Как я могу войти в свою пользовательскую модель пользователя? AuthenticationForm или моя собственная пользовательская форма входа не будут проверяться
Flutter и Supabase - глубокая ссылка OAuth не работает
Nextjs-auth0: обновить сеанс пользователя (без выхода/входа) после обновления user_metadata
FastAPI - невозможно получить токен аутентификации из объекта запроса промежуточного программного обеспечения
Почтовый запрос Axios для маршрута 'appName/v1/users/' (Джосер) выдает ошибку 401, но Почтальон не
Создание контекста PrivateRoute в React, который работает внутри блока Routes
Можно ли объявить маршруты react-router v6 в функциональном компоненте?