J'ai configuré mon application pour pouvoir envoyer des notifications Apple à l'aide de firebase et j'ai vérifié qu'elle fonctionnait à l'aide de la console. Maintenant, je veux faire l'authentification téléphonique qui est construite sur APN.
Alors j'ai écrit ceci:
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber) { verificationID, error in
if error != nil {
print("Verification code not sent \(error!)")
} else {
print ("Successful.")
}
Et je reçois:
Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={NSUnderlyingError=0x170046db0 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={
code = 500;
message = "<null>";
}}}, error_name=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information.}
Une idée? Devrais-je déposer un bogue contre firebase?
J'utilise iOS SDK 4.0.0 (le dernier fichier Zip que j'ai pu trouver.)
METTRE À JOUR:
J'ai désactivé la méthode swizzling en ajoutant FirebaseAppDelegateProxyEnabled
à info.plist
et en le réglant sur NO
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Pass device token to auth.
Auth.auth().setAPNSToken(deviceToken, type: .prod)
}
Testé avec les derniers SDK iOS Firebase i.e. 4.0.0 et Xcode 8.3
Tout d’abord, supprimez cette clé FirebaseAppDelegateProxyEnabled
de info.plist. Ce n'est pas nécessaire.
Maintenant dans AppDelegate.Swift ajouter les fonctions suivantes
import Firebase
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate , UNUserNotificationCenterDelegate{
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
FirebaseApp.configure()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Pass device token to auth.
let firebaseAuth = Auth.auth()
//At development time we use .sandbox
firebaseAuth.setAPNSToken(deviceToken, type: AuthAPNSTokenType.sandbox)
//At time of production it will be set to .prod
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let firebaseAuth = Auth.auth()
if (firebaseAuth.canHandleNotification(userInfo)){
print(userInfo)
return
}
}*
Envoyer un code de vérification au téléphone de l'utilisateur:
Dans la classe où vous souhaitez intégrer l'authentification téléphonique, écrivez:
Remarque : J'ai ajouté +91
comme code de pays pour l'Inde. Vous pouvez ajouter un code de pays en fonction de votre région.
PhoneAuthProvider.provider().verifyPhoneNumber("+919876543210") { (verificationID, error) in
if ((error) != nil) {
// Verification code not sent.
print(error)
} else {
// Successful. User gets verification code
// Save verificationID in UserDefaults
UserDefaults.standard.set(verificationID, forKey: "firebase_verification")
UserDefaults.standard.synchronize()
//And show the Screen to enter the Code.
}
Connectez-vous à l'utilisateur avec le code de vérification :
let verificationID = UserDefaults.standard.value(forKey: "firebase_verification")
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID! as! String, verificationCode: self.txtEmailID.text!)
Auth.auth().signIn(with: credential, completion: {(_ user: User, _ error: Error?) -> Void in
if error != nil {
// Error
}else {
print("Phone number: \(user.phoneNumber)")
var userInfo: Any? = user.providerData[0]
print(userInfo)
}
} as! AuthResultCallback)
Vérifiez deux fois que l'ID de l'ensemble d'applications dans Xcode correspond à celui de l'ensemble de Firebase exactement . Et par exactement , assurez-vous que leur casse correspond - Xcode aime utiliser des casse mixte par défaut pour la partie du nom d'application de l'ID de paquet.
Si vous modifiez l'ID de l'ensemble dans Xcode, assurez-vous de supprimer manuellement le profil d'approvisionnement de l'application avant d'en générer un nouveau dans Xcode, sinon le système échouera à plusieurs reprises (Apple ignore apparemment la casse des noms de profil).
Dans mon cas, c'était le type de jeton apns qui était incorrect:
Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.prod)
aurait du être:
Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.sandbox)
Eh bien, dans mon cas, j’ai mal envoyé self.verificationID
à FIRAuthCredential
. Si vous rencontrez cette erreur, imprimez votre verificationID
et vérifiez si c’est la même chose que vous envoyez à FIRAuthCredential
.
Voici mon code dans objC
:
[[FIRPhoneAuthProvider provider] verifyPhoneNumber:self.phoneNumberTextField.text
UIDelegate:nil
completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
if (error) {
NSLog(@"error %@", error.localizedDescription);
return;
}
NSLog(@"verificationID %@", verificationID);
self.verificationID = [NSString stringWithFormat:@"%@", verificationID];
// NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// [defaults setObject:verificationID forKey:@"authVerificationID"];
// NSString *verificationID = [defaults stringForKey:@"authVerificationID"];
// Sign in using the verificationID and the code sent to the user
// ...
}];
J'ai accidentellement envoyé un ID de vérification incorrect ici
self.verificationID = [NSString stringWithFormat:@"verificationID",];
La bonne est celle-ci:
self.verificationID = [NSString stringWithFormat:@"%@", verificationID];
Et puis je l'envoie à FIRAuthCredential
comme ceci:
FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
credentialWithVerificationID:self.verificationID
verificationCode:self.pinCodeTextField.text];
[[FIRAuth auth] signInWithCredential:credential
completion:^(FIRUser *user, NSError *error) {
if (error) {
NSLog(@"error %@", error);
return;
}
NSLog(@"Success");
// User successfully signed in. Get user data from the FIRUser object
// ...
}];
Quel retour success
avec succès. J'espère que cela aidera les autres.