ios - 使用 Firebase 电子邮件验证链接登录
问题描述
我正在使用Firebase
. 我已经配置了所有东西并发送了验证链接。
问题是当我点击验证链接时,它会打开我的应用程序,我会在AppDelegate
方法中获得链接。但由于某种原因,我无法使用此链接登录。这是我的代码
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
let handled = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
if let DeepLinkUrl = dynamiclink?.url?.absoluteString {
if DeepLinkUrl.contains("verifyEmail") {
if Auth.auth().isSignIn(withEmailLink: DeepLinkUrl) {
Auth.auth().signIn(withEmail: SBUserSetting.getVerificationEmail() ?? "", link: DeepLinkUrl ) { (user, error) in
print("user", user)
print("error", error)
}
}
}
}
}
return handled
}
Auth.auth().isSignIn()
总是返回false
你知道我在做什么错吗?
解决方案
如果您想使用无密码登录(此https://firebase.google.com/docs/auth/ios/email-link-auth#verify_link_and_sign_in),则不能使用从 url 到 DynamicLink 的转换。您只需要像这样将原始 url 传递给您的方法。
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let webpageUrl = userActivity.webpageURL {
if Auth.auth().isSignIn(withEmailLink: webpageUrl.absoluteString) {
// Saved email locally before, where you send verification, so you don't need to ask the user for it again
// if they open the link on the same device.
if let emailToVerify = UserDefaults.standard.string(forKey: "Email") {
Auth.auth().signIn(withEmail: emailToVerify, link: webpageUrl.absoluteString) { (user, error) in
if let error = error as NSError? {
print(error.localizedDescription)
} else {
// User is logged in
}
}
}
}
}
return true
}
但是如果你想使用方法sendEmailVerification你需要这个:
func sendEmailVerification() {
let actionCodeSettings = ActionCodeSettings()
actionCodeSettings.url = URL(string: "https://yourdomain.com")
// The sign-in operation has to always be completed in the app.
actionCodeSettings.handleCodeInApp = true
actionCodeSettings.setIOSBundleID(Bundle.main.bundleId) // Budle identifier of your application
Auth.auth().currentUser?.sendEmailVerification(with: actionCodeSettings, completion: { error in
if let error = error as NSError? {
print(error.localizedDescription)
} else {
// inform user about sending verification email
}
})
}
然后您可以使用 DynamicLink 类处理到达的电子邮件,如下所示:
func handleDynamicLink(_ url: URL?) -> Bool {
guard let url = url else { return false }
// Here don't know, which method will work, so I handle both for sure :-)
if !DynamicLinks.dynamicLinks().handleUniversalLink(url, completion: { dynamicLink, error in
if let dynamicLink = dynamicLink {
if let oobCode = dynamicLink.url?.getQueryString(parameter: "oobCode") {
Auth.auth().applyActionCode(oobCode) { error in
if let error = error as NSError? {
print(error.localizedDescription)
} else {
// Email was successfully verified
}
}
}
} else {
// Handle error
}
}) {
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
if let oobCode = dynamicLink.url?.getQueryString(parameter: "oobCode") {
Auth.auth().applyActionCode(oobCode) { error in
if let error = error as NSError? {
print(error.localizedDescription)
} else {
// Email was successfully verified
}
}
}
} else {
// handle error
}
}
return false
}
这是我自己的 url 扩展方法getQueryString,用于将组件与 url 分开。
extension URL {
func getQueryString(parameter: String) -> String? {
if let urlComponents = URLComponents(string: self.absoluteString) {
return urlComponents.queryItems?.filter({ item in item.name == parameter }).first?.value
}
return nil
}
}
推荐阅读
- reactjs - mapStateToProps 触发后组件未更新
- bigcommerce - 购物车 API:cart.data.data.cart_amount 计算不正确....我认为
- chef-infra - 如果 Chef 资源退出失败,如何设置适当的保护?
- python - 延迟调用芹菜任务卡住了
- jenkins - 检查构建步骤的声明性管道 = 失败然后触发下一个构建步骤,但不会使作业失败。
- tfs - TFS2015 脚本只能部署(而不是构建)吗?
- java - 此行中的错误“String forecastStr = mForecastAdapter.getItem(position);” 在阳光项目中
- php - 在 mySQL 中扩展餐厅数据库
- javascript - 停止后将 FlipClock.js 数字设置为零
- elasticsearch - 搜索多个值时如何在elasticsearch中搜索时键入