首页 > 解决方案 > 电话号码验证失败 - 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

到目前为止,这些是我的尝试:

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



}

  1. 尝试更改 FirebaseAuth 插件版本,就像在这篇文章中一样
  2. 更改了我的 URLSCHEMES,就像在这篇文章中一样

    我的 google.services-info.plist (复制黄色条纹) 在此处输入图像描述

    我的 info.plist URL SCHEMES (粘贴了黄色条纹) //注意第二项是 Facebook URL SCHEME 我的 URLSCHEMES

  3. 更改了我的 FirebaseAppDelegateProxyEnabled,就像在这篇文章中一样

在此处输入图像描述

  1. 按照Google Docs配置我的 Firebase APNs Auth Key 和 reCAPTCHA 验证

    在此处输入图像描述

在此处输入图像描述

  1. 在 Xcode 上配置我的签名和功能

在此处输入图像描述

标签: iosswiftflutterfirebase-authentication

解决方案


我有确切的问题,我做了一些更改,并使用下面的代码修复了它。

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]


推荐阅读