iOS开发-使用FireBase进行Google 使用FaceBook进行三方登录

前言

  • iOS开发中需要有Google登录和Facebook登录的地方。
  • 看前须知:下面使用到的ID和个人信息是自己创建的demo的ID,或者不是真实的,该篇文章只是为了分享,请使用自己的ID。

开发前准备

FireBase注册

  • 在 Firebase 开放平台添加项目并创建应用
  • 注册firebase
  • 使用自己的项目Bundle ID在firebase上注册
    在这里插入图片描述
  • 生成的 GoogleService-Info.plist 导入自己的项目 (注意和Info.plist同级)
    在这里插入图片描述

FaceBook注册

  • 这里的注册可以自行百度找一下,有很多例子,这里不赘述了

一些配置和库的导入

  • podfile导入
    pod 'Firebase/Auth'# login base
    pod 'GoogleSignIn', '~> 5.0.2'# login Google
    pod 'FBSDKLoginKit', '~> 6.0.0'# login Facebook
  • info -> URLScheme
  • 在 GoogleService-Info.plist 文件中找到REVERSED_CLIENT_ID对应的值
  • 在FaceBook上的注册的key,fb+key,例如fb123456789123456
    在这里插入图片描述

代码

Google登录代码

  • AppDelegate.m
#import <Firebase.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    
    

	// Firebase 初始化配置
	[FIRApp configure];
	[GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
    // 其他代码... 
    return YES;
}

- (BOOL)application:(nonnull UIApplication *)application
            openURL:(nonnull NSURL *)url
            options:(nonnull NSDictionary<NSString *, id> *)options {
    
    
    
    return [[GIDSignIn sharedInstance] handleURL:url];
}

//  ios(4.2, 9.0)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation {
    
    
    if ([url.absoluteString containsString:[FIRApp defaultApp].options.clientID]) {
    
    
        return [[GIDSignIn sharedInstance] handleURL:url];
    }
    return NO;
}

  • SceneDelegate.m 如果版本低没有SceneDelegate.m也可以不用配置
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts  API_AVAILABLE(ios(13.0)){
    
    
    
    UIOpenURLContext *openURLContext = URLContexts.allObjects.firstObject;
    if ([openURLContext.URL.absoluteString containsString:[FIRApp defaultApp].options.clientID]) {
    
    
        [[GIDSignIn sharedInstance] handleURL:openURLContext.URL];
    }
}

  • google登录点击事件处理
  • 非自定义按钮
#import <GoogleSignIn/GoogleSignIn.h>

// 遵守代理 <GIDSignInDelegate>

// 设置代理
[GIDSignIn sharedInstance].delegate = self;
// 必须设置 否则会Crash
[GIDSignIn sharedInstance].presentingViewController = self;

// Firebase 封装的 Google 登录按钮
GIDSignInButton *gidSignInBtn = [GIDSignInButton new];
gidSignInBtn.frame = CGRectMake(20.0, 120.0, 100.0, 40.0);
gidSignInBtn.center = self.view.center;
[self.view addSubview:gidSignInBtn];


// 实现代理方法
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error {
    
    
    
    if (!error) {
    
    
        NSLog(@"用户ID:%@", user.userID);
        
        GIDAuthentication *authentication = user.authentication;
        FIRAuthCredential *credential =
        [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
                                         accessToken:authentication.accessToken];
        NSLog(@"credential Provider:%@", credential.provider);
        // Firebase 身份验证
        // Summary
        // Asynchronously signs in to Firebase with the given 3rd-party credentials (e.g. a Facebook login Access Token, a Google ID Token/Access Token pair, etc.) and returns additional identity provider data.
        // 三方异步登录Firebase
        [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
    
    
            if (error) {
    
    
                NSLog(@"错误信息:%@", error.debugDescription);
            }
            if (!authResult) {
    
    
                NSLog(@"授权结果为空");
                return;
            }
            NSLog(@"Firebase uid:%@", authResult.user.uid);
            
            // 用于获取登录用户 Firebase token 信息交给服务端校验
            [[FIRAuth auth].currentUser getIDTokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) {
    
    
                if (error) {
    
    
                    
                    NSLog(@"获取当前token出现错误:%@", error);
                    return;
                }
                // Send token to your backend via HTTPS
                NSLog(@"Firebase当前用户 token 信息:%@", token);
           }];
            /**
             * 2020-03-06 20:48:46.859887+0800 FirebaseDemo[95438:3699395] credential Provider:google.com
             * 2020-03-06 20:48:47.914463+0800 FirebaseDemo[95438:3699395] Firebase uid:ma4dqHEO7JZm************QVE3
             * 2020-03-06 21:21:22.486530+0800 FirebaseDemo[95931:3798238] Firebase当前用户 token 信息:eyJhbGciOiJSUzI1NiIsImtpZCI6IjhjZjBjNjQyZDQ.*********4ZTRiZDc5OTkzOTZiNTY3NDAiLCJ0eX*********vbSJ9fQ.pvyaaG2dKKDH4CxO4VGiq_jcwDnmP************gQhHE-j-W
             // 这部分token 信息是 jwt 格式的内容
             */
        }];
    } else {
    
    
        NSLog(@"%@", error.debugDescription);
        self.userInfoLabel.text = error.debugDescription;
    }
}

  • 自定义按钮
#import <GoogleSignIn/GoogleSignIn.h>

@interface LoginView () <GIDSignInDelegate>

@property(nonatomic, strong) UIButton *googleLogin;

@end

@implementation LoginView

- (instancetype)initWithFrame:(CGRect)frame withSuperViewController:(UIViewController *)superViewController {
    
    
    if(self = [super initWithFrame:frame]) {
    
    
        [self addSubview:self.googleLogin];
    }
    return self;
}

- (void)layoutSubviews {
    
    
    [super layoutSubviews];
    [self.googleLogin mas_makeConstraints:^(MASConstraintMaker *make) {
    
    
        make.centerY.equalTo(self.mas_centerY);
        make.right.equalTo(self.mas_left).mas_offset(-48));
        make.size.mas_equalTo(CGSize(36, 36));
    }];
}

- (UIButton *)googleLogin {
    
    
    if(_googleLogin == nil) {
    
    
        _googleLogin = [[UIButton alloc]init];
        [_googleLogin setImage:[UIImage imageNamed:@"google"] forState:UIControlStateNormal];
        [_googleLogin addTarget:self action:@selector(googleLoginAction) forControlEvents:UIControlEventTouchUpInside];
        [GIDSignIn sharedInstance].delegate = self;
        [GIDSignIn sharedInstance].presentingViewController = self.superViewController;
    }
    return _googleLogin;
}

#pragma mark - google三方登录 实现代理方法

- (void)googleLoginAction {
    
    
    NSError *signOutError;
    BOOL status = [[FIRAuth auth] signOut:&signOutError];
    if (!status) {
    
    
        NSLog(@"Error signing out: %@", signOutError);
        return;
    }
    [[GIDSignIn sharedInstance] signIn];
}

- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error {
    
    
    __weak typeof(self) weakSelf = self;
    if (!error) {
    
    
        //NSLog(@"用户ID:%@", user.userID);
        
        GIDAuthentication *authentication = user.authentication;
        FIRAuthCredential *credential =
        [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
                                         accessToken:authentication.accessToken];
        //NSLog(@"credential Provider:%@", credential.provider);
        [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult *authResult, NSError *error) {
    
    
            if (error) {
    
    
                //NSLog(@"错误信息:%@", error.debugDescription);
            }
            if (!authResult) {
    
    
                //NSLog(@"授权结果为空");
                return;
            }
            //NSLog(@"Firebase uid:%@", authResult.user.uid);
            // 用于获取登录用户 Firebase token 信息交给服务端校验
            [[FIRAuth auth].currentUser getIDTokenWithCompletion:^(NSString *token, NSError *error) {
    
    
                if (error) {
    
    
                    
                    //NSLog(@"获取当前token出现错误:%@", error);
                    return;
                }
                // Send token to your backend via HTTPS
                // 这里的token就可以给服务端了
                //NSLog(@"Firebase当前用户 token 信息:%@", token);
            }];
        }];
    } else {
    
    
        //NSLog(@"%@", error.debugDescription); 授权结果为空
        //self.userInfoLabel.text = error.debugDescription;
    }
}

@end
  • google登录失败调用的函数
    - (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error

FaceBook登录代码

  • AppDelegate.m
#import <FBSDKLoginKit/FBSDKLoginKit.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    
    // 为了使用 Facebook SDK 应该调用如下方法
    [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    // 注册 FacebookAppID 就是上面的URL types fb123456789123456
    // static NSString *const kFacebookAppID = @"123456789123456";
    [FBSDKSettings setAppID:kFacebookAppID];
    return YES;
}


- (BOOL)application:(nonnull UIApplication *)application
            openURL:(nonnull NSURL *)url
            options:(nonnull NSDictionary<NSString *, id> *)options {
    
    
    
    if (@available(iOS 9.0, *)) {
    
    
        return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
    } else {
    
    
        // Fallback on earlier versions
    }
}

//  ios(4.2, 9.0)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation {
    
    
    if ([url.absoluteString containsString:kFacebookAppID]) {
    
    
        return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
    }
    return NO;
}

  • SceneDelegate.m 如果版本低没有SceneDelegate.m也可以不用配置
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts  API_AVAILABLE(ios(13.0)){
    
    
    
    UIOpenURLContext *openURLContext = URLContexts.allObjects.firstObject;
    if (openURLContext) {
    
    
        if ([openURLContext.URL.absoluteString containsString:kFacebookAppID]) {
    
    
             [[FBSDKApplicationDelegate sharedInstance] application:UIApplication.sharedApplication openURL:openURLContext.URL sourceApplication:openURLContext.options.sourceApplication annotation:openURLContext.options.annotation];
            return;
        }
    }
}

  • faceBook登录点击事件处理
  • 非自定义按钮
#import "FBSDKLoginKit.h"

// 遵守代理 <FBSDKLoginButtonDelegate>

// Firebase 封装的Facebook 登录按钮
FBSDKLoginButton *fbLoginBtn = [FBSDKLoginButton new];
fbLoginBtn.frame = CGRectMake(20.0, 100.0, 120.0, 40.0);
fbLoginBtn.center = self.view.center;
fbLoginBtn.delegate = self;
[self.view addSubview:fbLoginBtn];

// FBSDKLoginButtonDelegate 代理方法
- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error {
    
    
    
    if (error) {
    
    
        NSLog(@"错误信息:%@", error);
    } else {
    
    
        FIRAuthCredential *credential =
        [FIRFacebookAuthProvider credentialWithAccessToken:result.token.tokenString];
        NSLog(@"credential Provider:%@", credential.provider);
        // Firebase 身份验证
        // Summary
        // Asynchronously signs in to Firebase with the given 3rd-party credentials (e.g. a Facebook login Access Token, a Google ID Token/Access Token pair, etc.) and returns additional identity provider data.
        // 三方异步登录Firebase
        [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
    
    
            if (error) {
    
    
                NSLog(@"错误信息:%@", error.debugDescription);
            }
            if (!authResult) {
    
    
                NSLog(@"授权结果为空");
                return;
            }
            NSLog(@"Firebase uid:%@", authResult.user.uid);
            
            
            
            /**
             * 2020-03-06 20:35:42.995671+0800 FirebaseDemo[95438:3699395] token信息:<FBSDKAccessToken: 0x600001bf6580>
             * 2020-03-06 20:35:45.301482+0800 FirebaseDemo[95438:3699395] Firebase uid:X8U372A8****************s3s1
             * 2020-03-06 21:22:49.582470+0800 FirebaseDemo[95931:3798238] Firebase当前用户 token 信息:eyJhbGc*******************************************************AiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoi546L5rC45pe6IiwicGljdHVyZSI6Imh0dHBzOi8vZ3JhcGguZmFjZWJvb2suY29tLzEwMTAyNzQ5NDgxOTk4My9wa*******************************************************2tlbi5nb29nbGUuY29tL2Zpci1kZW1vLThkZj*******************************************************DM1MDA5NjgsInVzZXJfaWQiOiJYOFUzNzJBOG*******************************************************nlCdzNnS01nMXZ6czNzMSIsImlhdCI6MTU4MzUwMDk2OCwiZXhwIjoxNTgzNTA0NTY4LCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7ImZhY2Vib29rLmNvbSI6WyIxMDEwMjc0OTQ4MTk5ODMiXX0sInNpZ25faW5fcHJvdmlkZXIiOiJmYWNlYm9vay5jb20ifX0.VuhMUV_hr9Bc0Alrv2MS1X*******************************************************omeMXd5ebEe_FtKXEvSppDV8TN66p-*******************************************************lZpe-*******************************************************f-fyZ0lEK-p0PWB96WMKKY7jeVvPo_LR89u88kvjf7C-*******************************************************TWJmEYCMLqqtw9A
             */
            // 这部分token 信息是 jwt 格式的内容
        }];
        NSLog(@"token信息:%@", result.token);
        self.userInfoLabel.text = [NSString stringWithFormat:@"token信息:%@", result.token.tokenString];
        
    }
}

// 当点击 Facebook Log out 按钮的时候会调用这个代理方法
- (void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton {
    
    
    
    NSLog(@"退出登录");
}

  • 自定义按钮
#import <FBSDKLoginKit/FBSDKLoginKit.h>

@interface LoginView () <GIDSignInDelegate>

@property(nonatomic, strong) UIButton *fbLogin;

@end

@implementation LoginView

- (instancetype)initWithFrame:(CGRect)frame withSuperViewController:(UIViewController *)superViewController {
    
    
    if(self = [super initWithFrame:frame]) {
    
    
        [self addSubview:self.fbLogin];
    }
    return self;
}

- (void)layoutSubviews {
    
    
    [super fbLogin];
    [self.googleLogin mas_makeConstraints:^(MASConstraintMaker *make) {
    
    
        make.centerY.equalTo(self.mas_centerY);
        make.right.equalTo(self.mas_left).mas_offset(-48));
        make.size.mas_equalTo(CGSize(36, 36));
    }];
}

- (UIButton *)fbLogin {
    
    
    if(_fbLogin == nil) {
    
    
        _fbLogin = [[UIButton alloc]init];
        _fbLogin.layer.masksToBounds = YES;
        _fbLogin.layer.cornerRadius = 24;
        [_fbLogin addTarget:self action:@selector(facebookLoginAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _fbLogin;
}

#pragma mark - FBSDKLoginButtonDelegate 代理方法

- (void)facebookLoginAction {
    
    
    FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
    [loginManager logOut];
    [[FBSDKLoginManager new] logOut];
    
    [FBSDKProfile enableUpdatesOnAccessTokenChange:YES];
    
    __weak typeof(self) weakSelf = self;
    [loginManager logInWithPermissions:@[@"public_profile"] fromViewController:self.superViewController handler:^(FBSDKLoginManagerLoginResult * result, NSError *error) {
    
    
        if (error) {
    
    
            //NSLog(@"Process error");
        } else if (result.isCancelled) {
    
    
            //NSLog(@"Cancelled");授权结果为空
        } else {
    
    
            FIRAuthCredential *credential =
            [FIRFacebookAuthProvider credentialWithAccessToken:result.token.tokenString];
            NSLog(@"result.token.tokenString - %@", result.token.tokenString);
            __weak typeof(self) weakSelf = self;
            [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult *authResult, NSError *error) {
    
    
                if (error) {
    
    
                    //NSLog(@"错误信息:%@", error.debugDescription);
                }
                if (!authResult) {
    
    
                    //NSLog(@"授权结果为空");
                    return;
                }
                FIRUser *user = authResult.user;
                [user getIDTokenWithCompletion:^(NSString *token, NSError *error) {
    
    
	                // 这里可以拿到自己的token,返回服务端
                    }
                }];
                //NSLog(@"refreshToken uid:%@", user.refreshToken);
            }];
        }
    }];
}

@end

猜你喜欢

转载自blog.csdn.net/weixin_41732253/article/details/110262847
今日推荐