ios - 电话号码验证失败 - Flutter(仅限 iOS)
问题描述
我正在通过使用 Flutter 的 Firebase 身份验证实现 OTP 电话验证。在 Android 上它就像一个魅力,但另一方面,在 iOS 上我无法让它工作。这是我得到的错误:
请注意,我使用的是 OneSignal,它在 Android 和 iOS 上都可以正常工作
flutter:电话号码验证失败。代码:verifyPhoneNumberError。消息:如果禁用了应用代理调动,则 UIApplicationDelegate 接收到的远程通知需要转发到 FIRAuth 的 canHandleNotificaton: 方法。
我的颤振医生:
我的 CocoaPods:
我在 Flutter 上的 OPT 功能:
import 'package:firebase_auth/firebase_auth.dart';
class SMSFunctions {
/// Sends the code to the specified phone number.
static Future<void> sendCodeToPhoneNumber(
String phoneNo, Function onSuccess, Function onFailed) async {
FirebaseAuth.instance.signOut();
final PhoneVerificationCompleted verificationCompleted =
(AuthCredential user) {
print(
'Inside _sendCodeToPhoneNumber: signInWithPhoneNumber auto succeeded: $user');
};
final PhoneVerificationFailed verificationFailed =
(AuthException authException) {
print(
'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}');
onFailed();
};
final PhoneCodeSent codeSent =
(String verificationId, [int forceResendingToken]) async {
verificationId = verificationId;
print("code sent to " + phoneNo);
onSuccess(verificationId);
};
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) {
verificationId = verificationId;
print("time out");
onFailed();
};
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: phoneNo,
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
}
static Future<bool> confirmSMS(String smsCode, String verificationId) async {
print(smsCode);
print(verificationId);
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: smsCode,
);
AuthResult authResult;
try {
authResult = await FirebaseAuth.instance.signInWithCredential(credential);
print(authResult.user);
final FirebaseUser currentUser = authResult.user;
if (currentUser != null)
return true;
else
return false;
} catch (e) {
print(e);
}
return false;
}
}
插件版本:
firebase_auth: ^0.16.1
到目前为止,这些是我的尝试:
- 修改了我的 AppDelegate.swift,就像在这篇文章中一样
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Pass device token to auth
Auth.auth().setAPNSToken(deviceToken, type: .prod)
}
func application(_ application: UIApplication,
didReceiveRemoteNotification notification: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if Auth.auth().canHandleNotification(notification) {
completionHandler(.noData)
return
}
// This notification is not auth related, developer should handle it.
}
// For iOS 9+
func application(_ application: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
if Auth.auth().canHandle(url) {
return true
}
// URL not auth related, developer should handle it.
}
// For iOS 8-
func application(_ application: UIApplication,
open url: URL,
sourceApplication: String?,
annotation: Any) -> Bool {
if Auth.auth().canHandle(url) {
return true
}
// URL not auth related, developer should handle it.
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
for urlContext in URLContexts {
let url = urlContext.url
Auth.auth().canHandle(url)
}
// URL not auth related, developer should handle it.
}
func application(_ application: UIApplication,
didReceiveRemoteNotification notification: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if Auth.auth().canHandleNotification(notification) {
completionHandler(.noData)
return
}
// This notification is not auth related, developer should handle it.
handleNotification(notification)
}
}
- 尝试更改 FirebaseAuth 插件版本,就像在这篇文章中一样
更改了我的 URLSCHEMES,就像在这篇文章中一样
我的 google.services-info.plist (复制黄色条纹)
我的 info.plist URL SCHEMES (粘贴了黄色条纹) //注意第二项是 Facebook URL SCHEME
- 更改了我的 FirebaseAppDelegateProxyEnabled,就像在这篇文章中一样
按照Google Docs配置我的 Firebase APNs Auth Key 和 reCAPTCHA 验证
- 在 Xcode 上配置我的签名和功能
解决方案
我有确切的问题,我做了一些更改,并使用下面的代码修复了它。
AppDelegate.swift
import UIKit
import Flutter
import Firebase
import FirebaseAuth
import UserNotifications
import FirebaseInstanceID
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
return true
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let firebaseAuth = Auth.auth()
firebaseAuth.setAPNSToken(deviceToken, type: AuthAPNSTokenType.unknown)
}
override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let firebaseAuth = Auth.auth()
if (firebaseAuth.canHandleNotification(userInfo)){
print(userInfo)
return
}
}
}
我在下面添加的 Info.plist
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
我从下面的链接中得到了参考。[https://pub.dev/packages/firebase_messaging][1]