Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 469
fix(expo): register google sign in as expo module#8901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@clerk/expo': patch | ||
| --- | ||
| Fixes iOS builds that use native Google Sign-In by letting Expo Autolinking configure the required Google pod dependencies. |
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,23 +1,37 @@ | ||
| import React | ||
| import ExpoModulesCore | ||
| import GoogleSignIn | ||
| @objc(ClerkGoogleSignIn) | ||
| class ClerkGoogleSignInModule: NSObject, RCTBridgeModule { | ||
| public class ClerkGoogleSignInModule: Module { | ||
| private var clientId: String? | ||
| private var hostedDomain: String? | ||
| static func moduleName() -> String! { | ||
| return "ClerkGoogleSignIn" | ||
| } | ||
| public func definition() -> ModuleDefinition { | ||
| Name("ClerkGoogleSignIn") | ||
| @objc static func requiresMainQueueSetup() -> Bool { | ||
| return false | ||
| } | ||
| Function("configure") { (params: [String: Any?]) in | ||
| self.configure(params) | ||
| } | ||
| private var clientId: String? | ||
| private var hostedDomain: String? | ||
| AsyncFunction("signIn") { (params: [String: Any?]?, promise: Promise) in | ||
| self.signIn(params, promise: promise) | ||
| }.runOnQueue(.main) | ||
| AsyncFunction("createAccount") { (params: [String: Any?]?, promise: Promise) in | ||
| self.createAccount(params, promise: promise) | ||
| }.runOnQueue(.main) | ||
| AsyncFunction("presentExplicitSignIn") { (params: [String: Any?]?, promise: Promise) in | ||
| self.presentExplicitSignIn(params, promise: promise) | ||
| }.runOnQueue(.main) | ||
| AsyncFunction("signOut") { (promise: Promise) in | ||
| self.signOut(promise: promise) | ||
| }.runOnQueue(.main) | ||
| } | ||
| // MARK: - configure | ||
| @objc func configure(_ params: NSDictionary) { | ||
| private func configure(_ params: [String: Any?]) { | ||
| let webClientId = params["webClientId"] as? String ?? "" | ||
| let iosClientId = params["iosClientId"] as? String | ||
| self.clientId = iosClientId ?? webClientId | ||
| @@ -34,101 +48,91 @@ class ClerkGoogleSignInModule: NSObject, RCTBridgeModule { | ||
| // MARK: - signIn | ||
| @objc func signIn(_ params: NSDictionary?, | ||
| resolve: @escaping RCTPromiseResolveBlock, | ||
| reject: @escaping RCTPromiseRejectBlock) { | ||
| private func signIn(_ params: [String: Any?]?, promise: Promise) { | ||
| guard self.clientId != nil else { | ||
| reject("NOT_CONFIGURED", "Google Sign-In is not configured. Call configure() first.", nil) | ||
| promise.reject("NOT_CONFIGURED", "Google Sign-In is not configured. Call configure() first.") | ||
| return | ||
| } | ||
| DispatchQueue.main.async { | ||
| guard let presentingVC = self.getPresentingViewController() else { | ||
| reject("GOOGLE_SIGN_IN_ERROR", "No presenting view controller available", nil) | ||
| return | ||
| } | ||
| guard let presentingVC = self.getPresentingViewController() else { | ||
| promise.reject("GOOGLE_SIGN_IN_ERROR", "No presenting view controller available") | ||
| return | ||
| } | ||
| let filterByAuthorized = params?["filterByAuthorizedAccounts"] as? Bool ?? false | ||
| let hint: String? = filterByAuthorized | ||
| ? GIDSignIn.sharedInstance.currentUser?.profile?.email | ||
| : nil | ||
| let nonce = params?["nonce"] as? String | ||
| GIDSignIn.sharedInstance.signIn( | ||
| withPresenting: presentingVC, | ||
| hint: hint, | ||
| additionalScopes: nil, | ||
| nonce: nonce | ||
| ) { result, error in | ||
| self.handleSignInResult(result: result, error: error, resolve: resolve, reject: reject) | ||
| let filterByAuthorized = params?["filterByAuthorizedAccounts"] as? Bool ?? false | ||
| let hint: String? = filterByAuthorized | ||
| ? GIDSignIn.sharedInstance.currentUser?.profile?.email | ||
| : nil | ||
mikepitre marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| let nonce = params?["nonce"] as? String | ||
| GIDSignIn.sharedInstance.signIn( | ||
| withPresenting: presentingVC, | ||
| hint: hint, | ||
| additionalScopes: nil, | ||
| nonce: nonce, | ||
| completion: { result, error in | ||
| self.handleSignInResult(result: result, error: error, promise: promise) | ||
| } | ||
| } | ||
| ) | ||
| } | ||
| // MARK: - createAccount | ||
| @objc func createAccount(_ params: NSDictionary?, | ||
| resolve: @escaping RCTPromiseResolveBlock, | ||
| reject: @escaping RCTPromiseRejectBlock) { | ||
| private func createAccount(_ params: [String: Any?]?, promise: Promise) { | ||
| guard self.clientId != nil else { | ||
| reject("NOT_CONFIGURED", "Google Sign-In is not configured. Call configure() first.", nil) | ||
| promise.reject("NOT_CONFIGURED", "Google Sign-In is not configured. Call configure() first.") | ||
| return | ||
| } | ||
| DispatchQueue.main.async { | ||
| guard let presentingVC = self.getPresentingViewController() else { | ||
| reject("GOOGLE_SIGN_IN_ERROR", "No presenting view controller available", nil) | ||
| return | ||
| } | ||
| guard let presentingVC = self.getPresentingViewController() else { | ||
| promise.reject("GOOGLE_SIGN_IN_ERROR", "No presenting view controller available") | ||
| return | ||
| } | ||
| let nonce = params?["nonce"] as? String | ||
| let nonce = params?["nonce"] as? String | ||
| GIDSignIn.sharedInstance.signIn( | ||
| withPresenting: presentingVC, | ||
| hint: nil, | ||
| additionalScopes: nil, | ||
| nonce: nonce | ||
| ) { result, error in | ||
| self.handleSignInResult(result: result, error: error, resolve: resolve, reject: reject) | ||
| GIDSignIn.sharedInstance.signIn( | ||
| withPresenting: presentingVC, | ||
| hint: nil, | ||
| additionalScopes: nil, | ||
| nonce: nonce, | ||
| completion: { result, error in | ||
| self.handleSignInResult(result: result, error: error, promise: promise) | ||
| } | ||
| } | ||
| ) | ||
| } | ||
| // MARK: - presentExplicitSignIn | ||
| @objc func presentExplicitSignIn(_ params: NSDictionary?, | ||
| resolve: @escaping RCTPromiseResolveBlock, | ||
| reject: @escaping RCTPromiseRejectBlock) { | ||
| private func presentExplicitSignIn(_ params: [String: Any?]?, promise: Promise) { | ||
| guard self.clientId != nil else { | ||
| reject("NOT_CONFIGURED", "Google Sign-In is not configured. Call configure() first.", nil) | ||
| promise.reject("NOT_CONFIGURED", "Google Sign-In is not configured. Call configure() first.") | ||
| return | ||
| } | ||
| DispatchQueue.main.async { | ||
| guard let presentingVC = self.getPresentingViewController() else { | ||
| reject("GOOGLE_SIGN_IN_ERROR", "No presenting view controller available", nil) | ||
| return | ||
| } | ||
| guard let presentingVC = self.getPresentingViewController() else { | ||
| promise.reject("GOOGLE_SIGN_IN_ERROR", "No presenting view controller available") | ||
| return | ||
| } | ||
| let nonce = params?["nonce"] as? String | ||
| let nonce = params?["nonce"] as? String | ||
| GIDSignIn.sharedInstance.signIn( | ||
| withPresenting: presentingVC, | ||
| hint: nil, | ||
| additionalScopes: nil, | ||
| nonce: nonce | ||
| ) { result, error in | ||
| self.handleSignInResult(result: result, error: error, resolve: resolve, reject: reject) | ||
| GIDSignIn.sharedInstance.signIn( | ||
| withPresenting: presentingVC, | ||
| hint: nil, | ||
| additionalScopes: nil, | ||
| nonce: nonce, | ||
| completion: { result, error in | ||
| self.handleSignInResult(result: result, error: error, promise: promise) | ||
| } | ||
| } | ||
| ) | ||
| } | ||
| // MARK: - signOut | ||
| @objc func signOut(_ resolve: @escaping RCTPromiseResolveBlock, | ||
| reject: @escaping RCTPromiseRejectBlock) { | ||
| private func signOut(promise: Promise) { | ||
| GIDSignIn.sharedInstance.signOut() | ||
| resolve(nil) | ||
| promise.resolve() | ||
| } | ||
| // MARK: - Helpers | ||
| @@ -147,25 +151,23 @@ class ClerkGoogleSignInModule: NSObject, RCTBridgeModule { | ||
| return topVC | ||
| } | ||
| private func handleSignInResult(result: GIDSignInResult?, error: Error?, | ||
| resolve: @escaping RCTPromiseResolveBlock, | ||
| reject: @escaping RCTPromiseRejectBlock) { | ||
| private func handleSignInResult(result: GIDSignInResult?, error: Error?, promise: Promise) { | ||
| if let error = error { | ||
| let nsError = error as NSError | ||
| // Check for user cancellation | ||
| if nsError.domain == kGIDSignInErrorDomain && nsError.code == GIDSignInError.canceled.rawValue { | ||
| reject("SIGN_IN_CANCELLED", "User cancelled the sign-in flow", error) | ||
| promise.reject("SIGN_IN_CANCELLED", "User cancelled the sign-in flow") | ||
| return | ||
| } | ||
| reject("GOOGLE_SIGN_IN_ERROR", error.localizedDescription, error) | ||
| promise.reject("GOOGLE_SIGN_IN_ERROR", error.localizedDescription) | ||
| return | ||
| } | ||
| guard let result = result, | ||
| let idToken = result.user.idToken?.tokenString else { | ||
| reject("GOOGLE_SIGN_IN_ERROR", "No ID token received", nil) | ||
| promise.reject("GOOGLE_SIGN_IN_ERROR", "No ID token received") | ||
| return | ||
| } | ||
| @@ -187,6 +189,6 @@ class ClerkGoogleSignInModule: NSObject, RCTBridgeModule { | ||
| ] as [String: Any] | ||
| ] | ||
| resolve(response) | ||
| promise.resolve(response) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,13 @@ | ||
| import type { TurboModule } from 'react-native'; | ||
| import { TurboModuleRegistry } from 'react-native'; | ||
| import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypesNamespace'; | ||
| import { requireOptionalNativeModule } from 'expo'; | ||
| export interface Spec extends TurboModule { | ||
| configure(params: UnsafeObject): void; | ||
| signIn(params: UnsafeObject | null): Promise<UnsafeObject>; | ||
| createAccount(params: UnsafeObject | null): Promise<UnsafeObject>; | ||
| presentExplicitSignIn(params: UnsafeObject | null): Promise<UnsafeObject>; | ||
| type NativeMap = Record<string, unknown>; | ||
| interface Spec { | ||
| configure(params: NativeMap): void; | ||
| signIn(params: NativeMap | null): Promise<NativeMap>; | ||
| createAccount(params: NativeMap | null): Promise<NativeMap>; | ||
| presentExplicitSignIn(params: NativeMap | null): Promise<NativeMap>; | ||
| signOut(): Promise<void>; | ||
| } | ||
| export default TurboModuleRegistry.get<Spec>('ClerkGoogleSignIn'); | ||
| export default requireOptionalNativeModule<Spec>('ClerkGoogleSignIn'); |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.