6

クールな Firebase 電子メール リンク ログイン機能を実装しようとして失敗しています。メールリンクの送信を正常にセットアップしました。ただし、アプリを開くためのメール リンクを取得できません。アプリを開くことができないように、プレビュー ページを開くだけです。

セットアップした動的リンクをテストしたところ、デバイスでアプリを開くことができました。同じことをするための電子メールリンクを取得できません。

私のアプリのコード:

func sendFirebaseEmailLink() {

    let actionCodeSettings = ActionCodeSettings.init()

    // userEmail comes from a textField
    let email = userEmail

    actionCodeSettings.url = URL.init(string: String(format: "https://<myappname>.firebaseapp.com/?email=%@", email))
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)

    Auth.auth().sendSignInLink(toEmail: email,
        actionCodeSettings: actionCodeSettings) { error in

        if let error = error {
            print(error.localizedDescription)
            return
        }
        else {
            UserDefaults.standard.set(email, forKey: "Email")
            print("email sent to user")
        }
    }
}

アプリを開くための動的リンクを正常に取得したと言うとき、アプリがインストールされているデバイスで作成したリンク (mylinkname.page.link/emaillogin) をたどると、アプリが開きます。そのため、ダイナミック リンクの設定に関する [この役立つ Firebase ビデオ][1] のおかげで、これらの詳細は正しく、問題はコードにあるように見えますが、私はこれに慣れていないため、よくわかりません.

私はこれを理解するために円を描いて数日を費やし、密集した Firebase ドキュメントを解析しようとしました。

4

1 に答える 1

4

私はついにそれを理解しました。コードは大丈夫でした。動的リンクに関連する問題でした。ある時点で新しいバンドル ID を作成する必要があったため、Firebase にいくつかのリンクを設定しました。Firebase で古いものを削除すると、メール リンクが機能し始めました。

このようにアプリの関連付けサイトに表示され、古いリンクを削除しても奇妙なことにまだ表示されますが、少なくとも今は機能しています!

{"applinks":{"apps":[],"details":[{"appID":"TEAMID.com.OLDBUNDLEIDENTIFIER.APPNAME","paths":["NOT / /*","/*"] },{"appID":"TEAMID.com.NEWBUNDLEIDENTIFIER.APPNAME","パス":["NOT / / ","/ "]}]}}

更新:パスワードなしの電子メール ログインを実装するための私の完全なコードは以下のとおりです。ドキュメントを使用してつなぎ合わせるのは大変だったので、これで問題が解決することを願っています。

Firebase セットアップの基本を理解していることを前提とした主な手順。

1) Firebase Video チュートリアルを使用してダイナミック リンクを設定します。

2)View Controllerのコード:

var userEmail: String?
var link: String?

func sendFirebaseEmailLink() {

    let actionCodeSettings = ActionCodeSettings.init()
    let email = userEmail
    actionCodeSettings.url = URL.init(string: String(format: "https://<myappname>.page.link/emaillogin/?email=%@", email!))
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)

    Auth.auth().sendSignInLink(toEmail: email!,
        actionCodeSettings: actionCodeSettings) { error in

        if let error = error {
            print(error.localizedDescription)
            return
        }
        else {
            UserDefaults.standard.set(email, forKey: "Email")
            print("email sent to user")
        }

        // TODO: Notify user to check email and click the link.
    }
}

// Sign in user after they clicked email link called from AppDelegate
@objc func signInUserAfterEmailLinkClick() {

    // Get link url string from the dynamic link captured in AppDelegate.
    if let link = UserDefaults.standard.value(forKey: "Link") as? String {
        self.link = link
    }

    // Sign user in with the link and email.
    Auth.auth().signIn(withEmail: userEmail!, link: link!) { (result, error) in

        if error == nil && result != nil {

            if (Auth.auth().currentUser?.isEmailVerified)! {
                print("User verified with passwordless email")

                // TODO: Do something after user verified like present a new View Controller

            }
            else {
                print("User NOT verified by passwordless email")

            }
        }
        else {
            print("Error with passwordless email verfification: \(error?.localizedDescription ?? "Strangely, no error avaialble.")")
        }   
    }
}

3) AppDelegate のコード

// For Passwordless Email Login to Handle Dynamic Link after User Clicks Email Link
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {

    if let incomingURL = userActivity.webpageURL {
        print("Incoming URL is \(incomingURL)")

        // Parse incoming
        let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink, error) in

            guard error == nil else {
                print("Found an error: \(error!.localizedDescription)")
                return
            }
            if let dynamicLink = dynamicLink {
                self.handleIncomingDynamicLink(dynamicLink)
            }
        }
        if linkHandled {
            return true
        }
        else {
            // Maybe do other things with dynamic links in future?
            return false
        }
    }
    return false
}

// Handles the link and saves it to userDefaults to assist with login.
func handleIncomingDynamicLink(_ dynamicLink: DynamicLink) {
    guard let url = dynamicLink.url else {
        print("My dynamic link object has no url")
        return
    }
    print("Incoming link parameter is \(url.absoluteString)")

    let link = url.absoluteString
    if Auth.auth().isSignIn(withEmailLink: link) {

        // Save link to userDefaults to help finalize login.
        UserDefaults.standard.set(link, forKey: "Link")

        // Send notification to ViewController to push the First Time Login VC
        NotificationCenter.default.post(
            name: Notification.Name("SuccessfulPasswordlessEmailNotification"), object: nil, userInfo: nil)
    }
}
于 2019-04-18T12:02:46.180 に答える