Expo ile Google Authentication

Zafer Ayan
7 min readJul 7, 2023

--

Önceki yazımda Firebase entegrasyonuna değinmiştim. Bu yazımda da Google Auth nasıl entegre edeceğiz ona değineceğim.

Öncelikle projeyi oluşturalım

yarn create expo sample-google-auth

Sonrasında prebuild yaparak ios ve android dizinlerini oluşturalım:

npx expo prebuild --clean

Firebase Console üzerinde ios ve android projelerini oluşturup profile dosyalarını projeye ekleyelim.

Not: Android SHA1 keyi için şu komutu kullanabilirsiniz

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android |pcregrep -o1 "SHA1: (.+)"

App.json’daki ilgili alanları güncelleyelim:

{
"expo": {
"ios": {
"googleServicesFile": "./GoogleService-Info.plist"
},
"android": {
"googleServicesFile": "./google-services.json"
},
"plugins": [
"@react-native-firebase/app",
"@react-native-firebase/auth",
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "static"
}
}
]
]
}
}

Şimdi plugin’leri ekleyelim:

npx expo install @react-native-firebase/app @react-native-firebase/auth expo-build-properties

Artık uygulamamız authentication işlemleri içın hazır hale geldi. Şimdi anonim login işlemi getçekleştirerek kurduğumuz yapıyı test edelim.

Anonymous Login

Firebase console üzerinden SignIn Providers menüsünden Anonymous logini aktif hale getirelim:

Devamında App.js içerisinde butona tıklanıldığında login işlemi gerçekleştirecek kodu yazalım:

import { SafeAreaView, Button } from "react-native";
import auth from "@react-native-firebase/auth";

export default function App() {
const handleLogin = () => {
auth()
.signInAnonymously()
.then((res) => {
console.log("User signed in anonymously. ");
console.log(res.user);
})
.catch((error) => {
console.error(error);
});
};
return (
<SafeAreaView>
<Button title="Click me" onPress={handleLogin} />
</SafeAreaView>
);
}

Tıkladığınızda otomatik olarak login işlemi gerçekleştirilecek. Firebase Console ve terminal üzerinde user bilgilerini görebileceksiniz.

Anonim olarak user açabildiğimize göre entegrasyonumuz başarılı demektir. Şimdi Email/Password kullanarak giriş yaptırmayı deneyelim.

Email/Password Login

Firebase console üzerinden SignIn Providers menüsünden Email/Password aktif hale getirelim:

Provider seçeneğinde Email/Password kısmını aktif etmemiz yeterlidir.

Şimdi App.js dosyasını email/password girişi yapacak şekilde güncelleyelim:

import { SafeAreaView, Button, TextInput } from "react-native";
import auth from "@react-native-firebase/auth";
import { useState } from "react";

export default function App() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleLogin = () => {
auth()
.createUserWithEmailAndPassword(email, password)
.then(() => {
console.log("User account created & signed in!");
})
.catch((error) => {
console.error(error);
});
};
return (
<SafeAreaView>
<TextInput
placeholder="Email"
keyboardType="email-address"
onChangeText={setEmail}
/>
<TextInput
placeholder="Password"
secureTextEntry={true}
onChangeText={setPassword}
/>
<Button title="Create User" onPress={handleLogin} />
</SafeAreaView>
);
}

Aşağıdaki gibi email ve parola alanlarını doldurup Create User butonuna tıkladığınızda Firebase üzerinde kullanıcı oluşacaktır.

Firebase Console üzerinden oluşturduğunuz kullanıcıyı görebilirsiniz

Giriş yapmak için ise signInWithEmailAndPassword metodunu kullanabilirsiniz.

Çıkış yapma

Çıkış yapmak için signOut metodu aşağıdaki gibi kullanılabilir:

import { SafeAreaView, Button } from "react-native";
import auth from "@react-native-firebase/auth";

export default function App() {
const handleSignOut = () => {
auth()
.signOut()
.then(() => console.log("User signed out!"));
};
return (
<SafeAreaView>
<Button title="Sign out" onPress={handleSignOut} />
</SafeAreaView>
);
}

Giriş olma durumunu izleme aşamasına geçebiliriz. Böylelikle routing işlemleri de merkezi bir yerden yönetilebilir:

Login durumunu izleme

Uygulama içerisinde global olarak login durumunu dinlemek için onAuthStateChanged metodunu aşağıdaki gibi kullanabiliriz:

import { useState, useEffect } from "react";
import { Text, SafeAreaView } from "react-native";
import auth from "@react-native-firebase/auth";

export default function App() {
const [initializing, setInitializing] = useState(true);
const [user, setUser] = useState();

function onAuthStateChanged(user) {
setUser(user);
if (initializing) setInitializing(false);
}

useEffect(() => {
const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
return subscriber; // unsubscribe on unmount
}, []);

return (
<SafeAreaView>
{!initializing && user && <Text>Welcome {user.email}</Text>}
</SafeAreaView>
);
}

Şimdi Google Auth aşamasına geçebiliriz

Google ile Login

Google ile login işlemini gerçekleştirmek için öncelikle Firebase Console üzerinde aktif hale getirelim. Uygulama adı ve mail adresini istediğiniz şekilde girebilirsiniz:

Devamında google-signin kütüphanesini eklememiz gerekiyor. Aşağıdaki gibi yükleyelim:

npx expo install @react-native-google-signin/google-signin

Devamında app.json dosyasında plugins kısmına ekleyelim:

{
"expo": {
"plugins": [
"@react-native-firebase/app",
"@react-native-firebase/auth",
"@react-native-google-signin/google-signin",
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "static"
}
}
]
],
}
}

Login isteği atmadan önce Google SDK’ini ayarlamamız gerekiyor. Bunun için google-services.json dosyasındaki client/oauth_client/client_id kısmında yer alan client_type: 3 olan client_id’yi kullanabiliriz. “.apps.googleusercontent.com” kısmını çıkararak kullanmaya dikkat ediniz:

App.js içerisine şu şekilde ekleyelim:

import { GoogleSignin } from "@react-native-google-signin/google-signin";

GoogleSignin.configure({
webClientId: "575805126642-163oitqg69b0ciphdgi1ea1qptrbg021",
});

Devamında tıklama sonrası çalışacak kodu aşağıdaki gibi ekleyerek App.js’in son hali almasını sağlayalım:

import { useState, useEffect } from "react";
import { Text, SafeAreaView, Button } from "react-native";
import auth from "@react-native-firebase/auth";
import { GoogleSignin } from "@react-native-google-signin/google-signin";

GoogleSignin.configure({
webClientId: "575805126642-163oitqg69b0ciphdgi1ea1qptrbg021",
});

export default function App() {
const onGoogleButtonPress = async () => {
// Check if your device supports Google Play
await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
// Get the users ID token
const { idToken } = await GoogleSignin.signIn();

// Create a Google credential with the token
const googleCredential = auth.GoogleAuthProvider.credential(idToken);

// Sign-in the user with the credential
const response = await auth().signInWithCredential(googleCredential);
console.log(response);
};

return (
<SafeAreaView>
<Button title="Google Sign-In" onPress={onGoogleButtonPress} />
</SafeAreaView>
);
}

Artık butona tıklandıktan sonra login olma aşamaları gerçekleştirilerek aşağıdaki gibi terminale çıktı üretilecektir

Apple Login

Nisan 2020 ile birlikte Google/Facebook/Twitter gibi 3. parti login kütüphaneleri kullanan uygulamalara Apple Login zorunlu hale geldi. Ilgili yazıyı Apple sitesinden okuyabilirsiniz https://developer.apple.com/news/?id=09122019b . Android uygulamalar için ise böyle bir zorunluluk bulunmamakta.

Öncelikle Firebase üzerinde Apple Login’i aktif hale getirmemiz gerekiyor.

Sadece enable etmemiz yeterli. Diğer alanları doldurmanıza gerek yok.

Sonrasında react-native-apple-authentication kütüphanesini eklememiz gerekiyor. (Plugin olmadığı için pod install da yapmamız gerekli)

yarn add @invertase/react-native-apple-authentication

(cd ios && pod install)

Daha sonra proje ile ilgili ayarların XCode üzerinden uygulanması gerekiyor. Aşamalara bu linkten ulaşabilirsiniz:

Başlangıç ayarları yaptığınıza göre artık App.js’i aşağıdaki şekilde güncelleyebilirsiniz:

import React from "react";
import {
AppleButton,
appleAuth,
} from "@invertase/react-native-apple-authentication";
import { SafeAreaView } from "react-native";
import auth from "@react-native-firebase/auth";

export default function App() {
const handleAppleLogin = async () => {
// Start the sign-in request
const appleAuthRequestResponse = await appleAuth.performRequest({
requestedOperation: appleAuth.Operation.LOGIN,
requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
});

// Ensure Apple returned a user identityToken
if (!appleAuthRequestResponse.identityToken) {
throw new Error("Apple Sign-In failed - no identify token returned");
}

// Create a Firebase credential from the response
const { identityToken, nonce } = appleAuthRequestResponse;
const appleCredential = auth.AppleAuthProvider.credential(
identityToken,
nonce
);

// Sign the user in with the credential
const response = auth().signInWithCredential(appleCredential);
console.log(response);
};
return (
<SafeAreaView>
<AppleButton
buttonStyle={AppleButton.Style.WHITE}
buttonType={AppleButton.Type.SIGN_IN}
style={{
width: 160,
height: 45,
}}
onPress={handleAppleLogin}
/>
</SafeAreaView>
);
}

Uygulamanın görüntüsü aşağıdaki gibi olacaktır:

Bonus: Github login

Github için herhangi bir login kütüphanesi bulunmuyor. Bu nedenle webView ile uyarlamamız gerekiyor.

Öncelikle Firebase üzerinde Github Provider’ını ekleme adımına gelelim.

Burada ClientId ve Client Secret istediği için yeni bir sekmede de Github’a gidip bir Oauth app oluşturmamız gerekiyor. Bunun için Github’da Settings>DeveloperSettings>OAuth Apps>New Oauth App seçerek yeni bir uygulama oluşturalım.

Callback url kısmına Firebase’deki URL’i yapıştıralım. Register Application’a tıkladığınızda aşağıdaki gibi bir sayfaya atacak. Client secrets Generate a new client secret butonuna basarak bir client secret oluşturalım.

Client bilgilerini aşağıdaki gibi girebilirsiniz:

Github için ise aşağıdaki gibi auth code alıp access_token değerini sorgulatabilirsiniz:

import * as React from "react";
import * as WebBrowser from "expo-web-browser";
import { makeRedirectUri, useAuthRequest } from "expo-auth-session";
import { Button, SafeAreaView } from "react-native";
import auth from "@react-native-firebase/auth";

WebBrowser.maybeCompleteAuthSession();

const CLIENT_ID = "a732445baf43c6ec254c";
const CLIENT_SECRET = "0d2b4301a79e0a5b29673ac9bb3xxxxxxxxxxxx";

// Endpoint
const discovery = {
authorizationEndpoint: "https://github.com/login/oauth/authorize",
tokenEndpoint: "https://github.com/login/oauth/access_token",
revocationEndpoint:
"https://github.com/settings/connections/applications/a732445baf43c6ec254c",
};

export default function App() {
const [request, response, promptAsync] = useAuthRequest(
{
clientId: CLIENT_ID,
scopes: ["user:email"],
redirectUri: makeRedirectUri({
scheme: "com.zaferayan.samplegoogleauth",
}),
},
discovery
);

const handleAuthCode = async (code) => {
const accessToken = await fetch(
"https://github.com/login/oauth/access_token",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
code,
}),
}
)
.then((res) => res.text())
.then((data) => data.split("&")[0].split("=")[1]);
const credential = auth.GithubAuthProvider.credential(accessToken);
const response = await auth().signInWithCredential(credential);
console.log("response", response);
};

React.useEffect(() => {
if (response?.type === "success") {
const { code } = response.params;
handleAuthCode(code);
}
}, [response]);

return (
<SafeAreaView>
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();
}}
/>
</SafeAreaView>
);
}

Firebase’de users kısmına tıkladığınızda eklendiğini göreceksiniz

Sonuç olarak

Bu yazımızda Expo Firebase kullanarak Google ile giriş işlemlerini gerçekleştirdik. Facebook ile giriş ve Twitter ile giriş işlemleri için rnfirebase sitesine bakabilirsiniz: https://rnfirebase.io/auth/social-auth

Projenin son halini buradan edinebilirsiniz: https://github.com/ozcanzaferayan/sample-expo-auth

Bu yazımda eksik/hatalı olduğunu düşündüğünüz kısımlar varsa bana ulaşabilirsiniz. Sonraki yazımda tekrar görüşmek üzere…

--

--

Responses (1)