{"id":194,"date":"2025-06-02T10:26:43","date_gmt":"2025-06-05T03:15:43","guid":{"rendered":"https:\/\/badgameshow.com\/steven\/?p=194"},"modified":"2025-06-05T10:26:43","modified_gmt":"2025-06-05T03:15:43","slug":"swift-google%e7%99%bb%e5%85%a5","status":"publish","type":"post","link":"https:\/\/badgameshow.com\/steven\/swift\/swift-google%e7%99%bb%e5%85%a5\/","title":{"rendered":"Swift Google \u767b\u5165 Firebase \u7b2c\u4e09\u65b9\u4e32\u63a5\u5b8c\u5168\u6559\u5b78\uff082025 \u6700\u65b0\u7248\uff09\ud83d\udc50"},"content":{"rendered":"<h1>Swift Google \u767b\u5165 Firebase \u7b2c\u4e09\u65b9\u4e32\u63a5\u5b8c\u5168\u6559\u5b78\uff082025 \u6700\u65b0\u7248\uff09\ud83d\udc50<\/h1>\n<h2>\u7c21\u4ecb<\/h2>\n<p>\u5728iOS\u61c9\u7528\u7a0b\u5f0f\u4e2d\uff0c\u4f7f\u7528Google\u767b\u5165\u5df2\u6210\u70ba\u4e00\u9805\u57fa\u672c\u529f\u80fd\u3002Firebase\u4f5c\u70ba\u4e00\u500b\u6574\u5408\u7b2c\u4e09\u65b9\u767b\u5165\u7684\u5f37\u5927\u5de5\u5177\uff0c\u8b93\u958b\u767c\u8005\u53ef\u4ee5\u8f15\u9b06\u5be6\u73feFacebook\u3001Instagram\u7b49\u591a\u7a2e\u767b\u5165\u65b9\u5f0f\u3002\u672c\u6587\u5c07\u6559\u4f60\u5982\u4f55\u5728Swift\u4e2d\u5be6\u4f5cGoogle\u767b\u5165\uff0c\u4e26\u4f7f\u7528Firebase\u9032\u884c\u8eab\u4efd\u8a8d\u8b49\u3002<\/p>\n<h2>\u74b0\u5883\u8a2d\u5b9a<\/h2>\n<p>\u5728\u958b\u59cb\u4e4b\u524d\uff0c\u78ba\u8a8d\u4f60\u5df2\u7d93\u5b89\u88dd\u4e86\u4ee5\u4e0b\u5169\u500bpods\uff1a<\/p>\n<p>&#8220;`swift<br \/>\npod &#8216;GoogleSignIn&#8217;<br \/>\npod &#8216;Firebase\/Analytics&#8217;<br \/>\n&#8220;`<\/p>\n<p>\u57f7\u884c\u4ee5\u4e0b\u547d\u4ee4\u5b89\u88dd\uff1a<\/p>\n<p>&#8220;`swift<br \/>\npod install<br \/>\n&#8220;`<\/p>\n<p>\u63a5\u8457\uff0c\u524d\u5f80 [Firebase \u5275\u5c08\u6848](https:\/\/firebase.google.com\/?platform=ios&#038;cntapi=signin&#038;cntapp=Default+Demo+App&#038;cntpkg=com.google.samples.quickstart.SignInExample&#038;cnturl=https%3A%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fios%2Fstart%3Fver%3Dswift%26configured%3Dtrue&#038;cntlbl=Continue+with+Try+Sign-In) \u5275\u5efa\u4e00\u500b\u5c08\u6848\u4e26\u914d\u7f6eGoogle\u767b\u5165\u3002<\/p>\n<h2>\u6b65\u9a5f\u8a73\u89e3<\/h2>\n<h3>1. \u5275\u5efa Firebase \u5c08\u6848<\/h3>\n<p>![Firebase \u5c08\u6848\u5275\u5efa](https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/08\/wp_editor_md_f8deb0a77dcd48995d4259c9d6df7575.jpg)<\/p>\n<h3>2. \u6dfb\u52a0 iOS \u5c08\u6848<\/h3>\n<p>![\u6dfb\u52a0 iOS \u5c08\u6848](https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/08\/wp_editor_md_27647440f5ed1c2166c77bc8e13327a2.jpg)<\/p>\n<h3>3. \u4e0b\u8f09\u8a2d\u5b9a\u6a94<\/h3>\n<p>![\u4e0b\u8f09\u8a2d\u5b9a\u6a94](https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/08\/wp_editor_md_8c846d5a9d9884c4919e2b4c3512e1cf.jpg)<\/p>\n<h3>4. \u65b0\u589e\u5230 Xcode<\/h3>\n<p>![\u65b0\u589e\u5230 Xcode](https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/08\/wp_editor_md_1fa403d94e05c1df2f6f04796b0254b9.jpg)<\/p>\n<h3>5. \u8907\u88fd GoogleService-Info.plist \u4e2d\u7684 REVERSED_CLIENT_ID<\/h3>\n<p>![\u8907\u88fd REVERSED_CLIENT_ID](https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/08\/wp_editor_md_10c489e5774eb86280f69ba47c950fe2.jpg)<\/p>\n<h3>6. \u5230 Info.plist \u4e2d\u65b0\u589e URL Types<\/h3>\n<p>![\u65b0\u589e URL Types](https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/08\/wp_editor_md_ee51e95a6ad920f5dc40e8e6d69b1c02.jpg)<\/p>\n<h3>7. \u5728 AppDelegate \u4e2d\u65b0\u589e GIDSignInDelegate<\/h3>\n<p>![AppDelegate \u8a2d\u5b9a](https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/08\/wp_editor_md_36bd282bcc16b031ccae184d219cf792.jpg)<\/p>\n<h3>8. AppDelegate \u8a2d\u5b9a<\/h3>\n<p>\u5728 `applicationDidFinishLaunching` \u4e2d\u521d\u59cb\u5316 GIDSignIn\uff1a<\/p>\n<p>&#8220;`swift<br \/>\nimport GoogleSignIn<br \/>\nimport Firebase<\/p>\n<p>@UIApplicationMain<br \/>\nclass AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {<br \/>\n    var window: UIWindow?<\/p>\n<p>    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {<br \/>\n        FirebaseApp.configure()<br \/>\n        GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID<br \/>\n        GIDSignIn.sharedInstance().delegate = self<br \/>\n        return true<br \/>\n    }<\/p>\n<p>    @available(iOS 9.0, *)<br \/>\n    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {<br \/>\n        return GIDSignIn.sharedInstance().handle(url)<br \/>\n    }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<h3>9. \u5be6\u4f5c\u767b\u5165\u4e8b\u4ef6<\/h3>\n<p>\u5728 `LoginViewController` \u4e2d\u65b0\u589e\u767b\u5165\u6309\u9215\u8207\u4e8b\u4ef6\u8655\u7406\uff1a<\/p>\n<p>&#8220;`swift<br \/>\nimport UIKit<br \/>\nimport GoogleSignIn<\/p>\n<p>class LoginViewController: UIViewController, GIDSignInDelegate {<br \/>\n    override func viewDidLoad() {<br \/>\n        super.viewDidLoad()<br \/>\n        GIDSignIn.sharedInstance().presentingViewController = self<br \/>\n        GIDSignIn.sharedInstance().delegate = self<\/p>\n<p>        let signInButton = GIDSignInButton()<br \/>\n        signInButton.center = self.view.center<br \/>\n        self.view.addSubview(signInButton)<br \/>\n    }<\/p>\n<p>    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {<br \/>\n        if let error = error {<br \/>\n            print(&#8220;\u767b\u5165\u5931\u6557: \\(error.localizedDescription)&#8221;)<br \/>\n            return<br \/>\n        }<br \/>\n        \/\/ \u7372\u53d6\u4f7f\u7528\u8005\u8cc7\u8a0a<br \/>\n        let userId = user.userID<br \/>\n        let idToken = user.authentication.idToken<br \/>\n        let email = user.profile.email<br \/>\n        \/\/ \u4f7f\u7528 Firebase \u767b\u5165<br \/>\n        guard let authentication = user.authentication else { return }<br \/>\n        let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken, accessToken: authentication.accessToken)<br \/>\n        Auth.auth().signIn(with: credential) { (authResult, error) in<br \/>\n            if let error = error {<br \/>\n                print(&#8220;Firebase \u767b\u5165\u932f\u8aa4: \\(error.localizedDescription)&#8221;)<br \/>\n                return<br \/>\n            }<br \/>\n            \/\/ \u6210\u529f\u767b\u5165<br \/>\n            print(&#8220;\u4f7f\u7528\u8005 \\(email) \u6210\u529f\u767b\u5165&#8221;)<br \/>\n        }<br \/>\n    }<br \/>\n}<br \/>\n&#8220;`<\/p>\n<h3>\u932f\u8aa4\u8655\u7406<\/h3>\n<p>&#8211; **403\u932f\u8aa4**\uff1a\u78ba\u4fdd\u5728Firebase\u63a7\u5236\u53f0\u7684Authentication\u90e8\u5206\u555f\u7528Google\u767b\u5165\u3002<br \/>\n&#8211; \u78ba\u4fdd\u4f60\u7684OAuth 2.0\u5ba2\u6236\u7aefID\u8207Firebase\u5c08\u6848\u4e2d\u7684\u914d\u7f6e\u76f8\u7b26\u3002<\/p>\n<h2>Q&#038;A\uff08\u5e38\u898b\u554f\u984c\u89e3\u7b54\uff09<\/h2>\n<h3>Q1: \u5982\u4f55\u89e3\u6c7a\u767b\u5165\u904e\u7a0b\u4e2d\u7684\u932f\u8aa4\uff1f<\/h3>\n<p>A1: \u6aa2\u67e5Firebase\u63a7\u5236\u53f0\u4e2dGoogle\u767b\u5165\u662f\u5426\u555f\u7528\uff0c\u4e26\u78ba\u4fdd\u4f60\u7684App ID\u548cOAuth\u8a2d\u5b9a\u6b63\u78ba\u3002<\/p>\n<h3>Q2: \u5982\u4f55\u5728\u767b\u5165\u5f8c\u7372\u53d6\u4f7f\u7528\u8005\u8cc7\u6599\uff1f<\/h3>\n<p>A2: \u4f7f\u7528GoogleSignIn\u7684`didSignInFor`\u56de\u8abf\u4e2d\u7684`user`\u5c0d\u8c61\u53ef\u4ee5\u7372\u53d6\u4f7f\u7528\u8005\u7684\u8cc7\u8a0a\uff0c\u5982email\u548c\u540d\u7a31\u3002<\/p>\n<h3>Q3: Firebase\u8207Google\u767b\u5165\u7684\u5b89\u5168\u6027\u5982\u4f55\u4fdd\u969c\uff1f<\/h3>\n<p>A3: Firebase\u4f7f\u7528OAuth 2.0\u6a19\u6e96\u9032\u884c\u8eab\u4efd\u9a57\u8b49\uff0c\u4e26\u63d0\u4f9b\u5b89\u5168\u7684\u4ee4\u724c\u4ea4\u63db\u904e\u7a0b\uff0c\u78ba\u4fdd\u8cc7\u6599\u7684\u5b89\u5168\u6027\u3002<\/p>\n<p>&#8212;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Swift Google \u767b\u5165 Firebase &#8230;<\/p>\n","protected":false},"author":1,"featured_media":559,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[5],"tags":[42,41,40],"class_list":["post-194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-swift","tag-google","tag-googlesignin","tag-40"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/badgameshow.com\/steven\/wp-content\/uploads\/2020\/11\/cup-1-1.png","jetpack-related-posts":[],"jetpack_shortlink":"https:\/\/wp.me\/pcFK27-38","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/posts\/194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/comments?post=194"}],"version-history":[{"count":8,"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/posts\/194\/revisions"}],"predecessor-version":[{"id":1133,"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/posts\/194\/revisions\/1133"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/media\/559"}],"wp:attachment":[{"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/media?parent=194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/categories?post=194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badgameshow.com\/steven\/wp-json\/wp\/v2\/tags?post=194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}