Published on

Firebase authentication: google orqali tizimga kirish (sign in with google)

Authors

Nega aynan google Sign-In?

Deyarli barcha zamonaviy dasturlarda foydalanuvchilar akkaunt ochish o'rniga shunchaki o'zlarining Google, Apple yoki Facebook akkauntlari orqali bir marta bosish orqali ro'yxatdan o'tishni ma'qul ko'rishadi. Bu ham siz (dasturchi) uchun, ham foydalanuvchi uchun juda qulay:

  • Foydalanuvchi yangi parol o'ylab topishi va uni eslab qolishi shart emas.
  • Siz dasturchi sifatida ularning parolini bazada xavfsiz saqlash, parolni tiklash (reset password) kabi murakkab tizimlar bilan shug'ullanmaysiz. Agar ular Google parolini unutib qo'ysa, buni Google'ning o'zi hal qilib beradi.

1-qadam: Firebase Konsolida faollashtirish

  1. Firebase Consolega kiring va loyihangizni oching.
  2. Authentication -> Sign-in method bo'limiga o'ting.
  3. Add new provider (Yangi provayder qo'shish) tugmasini bosib, Google'ni tanlang va uni yoqing (Enable).
  4. Bu yerda sizdan dasturingiz nomini (Public-facing name) hamda qo'llab-quvvatlash uchun email kiritish so'raladi. Ularni to'ldirib, saqlang.

2-qadam: Google Sign-In SDK'sini loyihaga qo'shish

Firebase o'z ichida Google Sign-In imkoniyatini taqdim etmaydi. Buning uchun Google'ning maxsus mustaqil iOS SDK'si kerak bo'ladi.

  1. Xcode'dan File -> Add Packages... menyusini tanlang.
  2. Qidiruv qatoriga quyidagi GitHub havolasini kiriting: https://GitHub.com/google/GoogleSignIn-iOS
  3. Kutubxonani loyihaga qo'shing.

3-qadam: URL Types konfiguratsiyasi

Google orqali kirish bosilganda ilovangizdan tashqariga chiqib brauzer yoki modal oyna ochiladi. U yerdan muvaffaqiyatli o'tgach, dastur yana sizning ilovangizga qaytishi kerak. Buni amalga oshirish uchun biz ilovaga o'zimizning URL Scheme'ni tanitib qo'yishimiz kerak.

  1. Xcode'da loyiha fayliga bosing va Target -> Info bo'limiga o'ting.
  2. Pastroqqa tushib, URL Types deb nomlangan qismni toping va + tugmasini bosing.
  3. URL Schemes degan maydonga REVERSED_CLIENT_ID ni yozishimiz kerak. Uni qayerdan olamiz?
  4. Loyihangizdagi GoogleService-Info.plist faylini oching. O'sha yerdan REVERSED_CLIENT_ID qatorini toping va uning qiymatini (com.googleusercontent.apps. bilan boshlanadi) nusxalab oling.
  5. Nusxalangan qiymatni URL Schemes maydoniga joylashtiring.

4-qadam: UI (Google tugmasi)

SwiftUI uchun Google o'zining rasmiy tugmasini taqdim etgan. Uni GoogleSignInSwift kutubxonasi orqali ishlata olamiz. Apple ham aynan rasmiy tugmalardan foydalanishni talab qiladi (ayniqsa Sign in with Apple'da).

import SwiftUI
import GoogleSignInSwift // <-- SDK ni chaqiramiz

struct AuthenticationView: View {
    @StateObject private var viewModel = AuthenticationViewModel()

    var body: some View {
        VStack {
            // ... Email bilan kirish tugmasi ...

            // Google bilan kirish tugmasi
            GoogleSignInButton(viewModel: GoogleSignInButtonViewModel(scheme: .dark, style: .wide, state: .normal)) {
                Task {
                    do {
                        try await viewModel.signInGoogle()
                    } catch {
                        print(error)
                    }
                }
            }
        }
    }
}

5-Qadam: top view controller'ni topish (Utilities)

Bu eng g'alati joylaridan biri. Google SDK SwiftUI bilan to'g'ridan-to'g'ri ishlamaydi. Tizimga kirish modalini ko'rsatish uchun unga eng yuqori turgan (topmost) UIViewController ni berishimiz kerak. Buni topish uchun Utilities degan alohida klass yaratamiz:

import Foundation
import UIKit

final class Utilities {
    static let shared = Utilities()
    private init() {}

    @MainActor
    func topViewController(controller: UIViewController? = nil) -> UIViewController? {
        let controller = controller ?? UIApplication.shared.keyWindow?.rootViewController

        if let navigationController = controller as? UINavigationController {
            return topViewController(controller: navigationController.visibleViewController)
        }
        if let tabController = controller as? UITabBarController {
            if let selected = tabController.selectedViewController {
                return topViewController(controller: selected)
            }
        }
        if let presented = controller?.presentedViewController {
            return topViewController(controller: presented)
        }
        return controller
    }
}

6-qadam: Sign In Helper va Firebase'ga ulash

Kodimiz chalkashib ketmasligi va istalgan ilovada qayta ishlatishimiz uchun Google mantiqini alohida SignInGoogleHelper klassiga joylashtiramiz. Bu klass bizga kerakli tokenni (ID Token va Access Token) olib beradi. Va nihoyat u orqali Firebase Auth yordamida kiramiz.

Birinchi navbatda keladigan ma'lumot modelini tuzib olamiz:

struct GoogleSignInResultModel {
    let idToken: String
    let accessToken: String
    let name: String?
    let email: String?
}

Helper klass:

import Foundation
import GoogleSignIn
import GoogleSignInSwift

final class SignInGoogleHelper {
    @MainActor
    func signIn() async throws -> GoogleSignInResultModel {
        guard let topVC = Utilities.shared.topViewController() else {
            throw URLError(.cannotFindHost)
        }

        // Google orqali avtorizatsiya oynasini ochamiz
        let gidSignInResult = try await GIDSignIn.sharedInstance.signIn(withPresenting: topVC)

        // Tokenlarni ajratib olamiz
        guard let idToken = gidSignInResult.user.idToken?.tokenString else {
            throw URLError(.badServerResponse)
        }
        let accessToken = gidSignInResult.user.accessToken.tokenString

        // User ism va emailini olish (Bazaga saqlash uchun kerak bo'ladi)
        let name = gidSignInResult.user.profile?.name
        let email = gidSignInResult.user.profile?.email

        return GoogleSignInResultModel(idToken: idToken, accessToken: accessToken, name: name, email: email)
    }
}

Endi bu tokenlarni olgach, AuthenticationManager yordamida Firebase tizimiga kiritamiz:

// AuthenticationManager.swift ichida
func signInWithGoogle(tokens: GoogleSignInResultModel) async throws -> AuthDataResultModel {
    let credential = GoogleAuthProvider.credential(withIDToken: tokens.idToken, accessToken: tokens.accessToken)
    let authDataResult = try await Auth.auth().signIn(with: credential)
    return AuthDataResultModel(user: authDataResult.user)
}

Va nihoyat, View Model'dagi asosiy funksiya qanday ishlaydi?

func signInGoogle() async throws {
    // 1-qadam: Google'dan tokenlarni va foydalanuvchi ma'lumotlarini olish
    let helper = SignInGoogleHelper()
    let tokens = try await helper.signIn()

    // 2-qadam: O'sha tokenlar orqali Firebase'ga kirish
    try await AuthenticationManager.shared.signInWithGoogle(tokens: tokens)
}

Xulosa

Endi dasturni ishga tushirsangiz va Sign in with Google tugmasini bossangiz, sizni brauzerga o'tkazadi va parolingizsiz hisobingizga muvaffaqiyatli kiritadi. Firebase Console -> Authentication -> Users bo'limida yangi foydalanuvchi "Google" provayderi orqali ro'yxatdan o'tganini ko'rishingiz mumkin bo'ladi! Keyingi videoda huddi shu kabi mantiq orqali Sign in with Apple ni qo'shamiz.

Buy mea coffee