如何访问Future方法|Dart中存在的回调函数的返回值



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);
}
}

登录.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的任何回调的值,例如返回异常消息的validationFailed,我想在外部访问它,以便在其他小部件中使用它。

到目前为止我尝试了什么

1( 我尝试过打印它,它返回AuthException Closure:((=>字符串我不知道如何访问该值。

2( 我尝试过使用setState,但由于我的类不在statefulWidget中,我无法将该值分配给变量

*我为什么需要它*

看,我有两个页面,一个叫login.dart,第二个叫auth.dart。在我的身份验证页面中,我主要放置与后端相关的类和代码(以正确组织代码(,在登录页面中我有一个有状态的小部件,考虑到电话文本字段和提交时,我调用方法signInWithPhone。一切正常,但如果出现任何错误,如用户电话号码格式错误,则会触发verificationFailed回调,因此我想访问外部的返回值(因为我们无法直接获取返回值(,以便我可以从我调用的位置显示它

有人能帮我吗?这样我就可以继续我的代码了。

现在很清楚你要做什么了。使用Provider是一种方法。另一种方法是将回调传递到登录页面:

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
})
})
}
)
]
)
);
}

}

我建议你让你的小部件有状态,然后你可以这样做:

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/@Jignesh Patel23/如何实现身份验证-签名-提供程序-内置-1f351447d09d

最新更新