Google SignIn 始终返回“The user canceled the sign-in flow”错误如何解决
谷歌登录Code=-5(用户取消登录流程)错误排查与解决方案
完整报错信息:Error Domain=com.google.GIDSignIn Code=-5 "The user canceled the sign-in flow." UserInfo={NSLocalizedDescription=The user canceled the sign-in flow.}
问题原因
- 未配置Info.plist对应的URL Schemes,授权完成后无法正常跳转回当前App,SDK判定为流程取消
- 登录调用时传入的presenting控制器无效,导致登录弹窗无法正常弹出
- AppDelegate/SceneDelegate中未实现Google登录的回调处理方法,SDK无法接收授权结果
- 项目使用的ClientID与Google后台配置的Bundle ID不匹配,授权请求被拦截
- 本地存在残留的无效登录状态,导致新的登录请求被直接中断
解决方案
1. 配置Info.plist的URL Schemes
打开项目Info配置页,找到URL Types,添加一条新的URL Scheme,值为你的Firebase ClientID的反转字符串(例如ClientID为xxx.apps.googleusercontent.com,反转后为com.googleusercontent.apps.xxx)。
也可以直接修改Info.plist源码添加:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>替换为你的反转ClientID</string> </array> </dict> </array>
2. 校验presenting控制器有效性
修改getWindowTopController()方法,确保返回的是当前最顶层的未销毁可见控制器:
func getWindowTopController() -> UIViewController? { guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }), var topController = window.rootViewController else { return nil } while let presentedController = topController.presentedViewController { topController = presentedController } return topController }
调用登录前先判断控制器是否存在:
guard let presentingVC = getWindowTopController() else { return } GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: presentingVC) { user, error in // 原有逻辑 }
3. 实现授权回调处理
- 采用AppDelegate的项目,在AppDelegate中添加openURL处理:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { return GIDSignIn.sharedInstance.handle(url) }
- 适配iOS 13+使用SceneDelegate的项目,在SceneDelegate中添加:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let url = URLContexts.first?.url else { return } GIDSignIn.sharedInstance.handle(url) }
4. 校验配置一致性
核对Firebase/Google Cloud后台配置的Bundle ID与项目的Bundle ID完全一致,确认使用的ClientID没有复制错误。
5. 清除本地无效登录状态
建议在触发新登录前统一清除本地缓存的授权状态,避免残留记录影响新的登录请求:
GIDSignIn.sharedInstance.signOut() GIDSignIn.sharedInstance.disconnect() // 可选,清除关联的授权记录 // 再执行你原有的登录判断逻辑
内容的提问来源于stack exchange,提问作者bAthi
相关产品推荐
相关产品推荐

