Как получить доступ к возвращаемому значению функции обратного вызова, присутствующей внутри метода Future | дротик - PullRequest
0 голосов
/ 09 апреля 2020

auth.dart

class AuthService {

  final FirebaseAuth _auth = FirebaseAuth.instance;

  // Sign in with Phone Number Future<bool>
  Future signInWithPhone(String phone, BuildContext context) async {

    final PhoneVerificationCompleted verificationCompleted = (AuthCredential credential) async {
      ..
    };

    final PhoneVerificationFailed verificationFailed = (AuthException exception) {
      // This is the return value which i want to access outside of this callback
      return exception.message;
    };

    final PhoneCodeSent codeSent = (String verificationId, [int forceResendingToken]) {
        ...
    };

    final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout = (String verificationId) {
        Navigator.of(context).pop();
        ...
    };

    await _auth.verifyPhoneNumber(
      phoneNumber: phone,
      timeout: Duration(seconds: 10),
      verificationCompleted: verificationCompleted,
      verificationFailed: verificationFailed,        
      codeSent: codeSent,
      codeAutoRetrievalTimeout: codeAutoRetrievalTimeout
    );

    // Trying to access the callback value
    print(verificationFailed);
 }
}

login.dart

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {

  @override
  Widget build(BuildContext context) {
    return Container(

     // here i am calling the phonesign in method
      await _auth.signInWithPhone(phoneNumber, context);

     // and here i want to show the message

    );
  }

}

В чем проблема?

Проблема в том, что я хочу получить доступ к значению любого обратного вызова verifyPhoneNumber , например, verifyFailed , который возвращает сообщение об исключении, и я хочу получить к нему доступ снаружи, поэтому что я могу использовать это в других виджетах.

Что я пробовал до сих пор?

1) Я попытался распечатать его, и он возвращает Закрытие AuthException: () => Строка Я не знаю, как получить доступ к значению.

2) Я пытался использовать setState , но мой класс не находится внутри statefulWidget Я не могу присвоить это значение переменной

* Зачем мне это нужно? *

Смотри, у меня есть две страницы, одна называется login.dart, а вторая называется auth.dart. На моей странице авторизации я в основном размещаю классы и код, относящиеся к бэкэнду (чтобы правильно организовать код ) и на странице входа в систему у меня есть виджет с состоянием, состоящий из текстового поля телефона, и при отправке я вызываю метод signInWithPhone . Все работает, но если появляется какая-либо ошибка, например, неправильный телефон пользователя затем запускается обратный вызов verifyFailed , и поэтому я хочу получить доступ к возвращаемому значению снаружи (bcz мы не можем напрямую получить возвращаемое значение), чтобы я мог показать его там, где я звонил это.

Может кто-нибудь, пожалуйста, помогите мне, чтобы я мог продолжить мой код.

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Теперь понятно, что ты пытаешься сделать. Использование провайдера - один из способов сделать это. Другой способ - передать обратный вызов на страницу входа:

class LoginPage extends StatefulWidget {
      final Function(String) verificationMessage;

      const LoginPage({Key key, this.verificationMessage}) : super(key: key);

     @override
     _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
    …
    …
    final PhoneVerificationFailed verificationFailed = (AuthException exception) {

       widget.verificationMessage(exception.message);’
    };
}

Теперь вы просто передаете функцию обратного вызова при каждом вызове LoginPage

LoginPage(verificationMessage: (String message) => {
    setState(() {
        // Do what you want with the message
    })
})

В вашем случае:

auth.dart

class AuthService {

  **final Function(String) verificationMessage;**
  **AuthService({@required this.verificationMessage});**

  final FirebaseAuth _auth = FirebaseAuth.instance;

  // Sign in with Phone Number Future<bool>
  Future signInWithPhone(String phone, BuildContext context) async {

    final PhoneVerificationCompleted verificationCompleted = (AuthCredential credential) async {
      ..
    };

    final PhoneVerificationFailed verificationFailed = (AuthException exception) {
      // This is the return value which i want to access outside of this callback
       **verificationMessage(exception.message);**
    };

    final PhoneCodeSent codeSent = (String verificationId, [int forceResendingToken]) {
        ...
    };

    final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout = (String verificationId) {
        Navigator.of(context).pop();
        ...
    };

    await _auth.verifyPhoneNumber(
      phoneNumber: phone,
      timeout: Duration(seconds: 10),
      verificationCompleted: verificationCompleted,
      verificationFailed: verificationFailed,        
      codeSent: codeSent,
      codeAutoRetrievalTimeout: codeAutoRetrievalTimeout
    );

    // Trying to access the callback value
    print(verificationFailed);
 }
}

login.dart

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {

  String message = "";

  @override
  Widget build(BuildContext context) {
    return Container(
         child: Column( 
          children: [
            Text(message),
            Flatbutton(
              .... 
              onPressed: (){
               AuthService(verificationMessage: (String newMessage) => {
                 setState(() {
                   message = newMessage
                 })
               })
              }
            )
          ]
         )
    );
  }



}
1 голос
/ 09 апреля 2020

Я предлагаю вам сделать ваш виджет с состоянием, тогда вы можете сделать это:

final PhoneVerificationFailed verifiFailed = (AuthException exception) {
  setState(() {
    errorMessage = exception.message;
  });

  print('${exception.message}');
};

Очень легко переключить ваш виджет на состояние:

class LoginPage extends StatefulWidget {

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  @override
  Widget build(BuildContext context) {

   return Column(children: [
       ...
       errorMessage == null ? SizedBox() : Text( errorMessage),
       ...
   ]);
  }
}

Когда errorMessage обновляется внутри setState будет отображаться сообщение об ошибке.

Вы также можете использовать Provider; Вот несколько ссылок для поиска:

https://medium.com/flutter-community/flutter-firebase-login-using-provider-package-54ee4e5083c7

https://www.youtube.com/watch?v=MjY1_LaXyd8

https://medium.com/@JigneshPatel23 / как к орудию-ан-аутентификации-функции-используя-а-провайдера-в-трепетание-1f351447d09d

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