Expo ile Google Authentication
Ö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.
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…