Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Firebase Auth & gAPI?

How do I get Firebase Auth to work with Google drive api?

Using react, I have firebase auth working and google drive (gapi) both working individually but am struggling to merge the two.

With Firebase 9, it's been made easier to access Google API: This gives you a Google Access Token. You can use it to access Google APIs.

My thinking is to get the token and then pass that to the gapi .init function. However, I'm not sure where to go after that. Any guidance in the right direction would be greatly appreciated!

import { getAuth, getRedirectResult, GoogleAuthProvider } from "firebase/auth";

onst auth = getAuth();
signInWithPopup(auth, provider)
  .then((result) => {
    // This gives you a Google Access Token. You can use it to access the Google API.
    const credential = GoogleAuthProvider.credentialFromResult(result);
    const token = credential.accessToken;

My gapi implementation:

useEffect(() => {
    window.gapi.load("client:auth2", initClient);
  }, []);

  useEffect(() => {
    if (authState) {
      authState.isSignedIn.listen(updateSigninStatus);
    }
  }, [authState]);

  const initClient = () => {
    try {
      window.gapi.auth2
        .init({
          apiKey: "API KEY...",
          clientId:
            "CLIENT ID...",
          scope: "https://www.googleapis.com/auth/drive",
          discoveryDocs: [
            "https://www.googleapis.com/discovery/v1/apis/drive/v3/rest",
          ],
        })
        .then(() => {
          const authInstance = window.gapi.auth2.getAuthInstance();
          setAuthState(authInstance);
        });
    } catch (err) {
      console.log(err);
    }
  };

  const signInFunction = () => {
    authState.signIn();
    updateSigninStatus();
  };

  const signOutFunction = () => {
    authState.signOut();
  };

  const updateSigninStatus = () => {
    setSigninStatus();
  };

  const setSigninStatus = async () => {
     //code...
      }
    }
  };
like image 474
InquisitiveTom Avatar asked Jun 28 '26 11:06

InquisitiveTom


1 Answers

I was struggling with the same thing and then I heard the Fireship guy talking about how easier it was to do it the other way around - sign in with gapi and pass credentials to Firebase.

I'm gonna share the way I did it, so you can relate to the solution and apply it to your project.

Initiate gapi using gapi-script in a gapi.js file and export gapi instance which you will use throughout the app.

import { gapi } from 'gapi-script'

gapi.load('client:auth2', async () => {
  gapi.client.init({
    apiKey: <YOUR_API_KEY>,
    clientId: <YOUR_GAPI_CLIENT_ID>,
    scope: 'https://www.googleapis.com/auth/drive.metadata.readonly',
    discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  })

  gapi.client.load('drive', 'v3', () => {})
})

export default gapi

Then initiate Firebase in a separate file as follows:

import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
  apiKey: <YOUR_FIREBASE_API_KEY>,
  authDomain: <YOUR_FIREBASE_AUTH_DOMAIN>,
  projectId: <YOUR_FIREBASE_PROJECT_ID>,
  storageBucket: <YOUR_FIREBASE_STORAGE_BUCKET>,
  messagingSenderId: <YOUR_FIREBASE_MESSAGING_SENDER_ID>,
  appId: <YOUR_FIREBASE_APP_ID>,
  clientId: <YOUR_FIREBASE_CLIENT_ID>,
  scopes: ['email', 'profile', 'https://www.googleapis.com/auth/drive.metadata.readonly'],
  discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
}

const firebaseApp = initializeApp(firebaseConfig)
const firebaseAuth = getAuth(firebaseApp)

export { firebaseApp, firebaseAuth }

And finally, in the auth.js file you can define functions that will be used throughout the project. You will notice that after logging in id_token is being grabbed from the auth response and passed as a credential to GoogleAuthProvider.

import { GoogleAuthProvider, signOut, signInWithCredential } from 'firebase/auth'
import { firebaseAuth } from './firebaseConfig'
import gapi from '../gapi'

/**
 * Sign in using gapi and pass credential to Firebase
 * Needs to be configured in https://console.firebase.google.com/u/0/project/<YOUR_PROJECT>/authentication/providers
 * by passing Web SDK Configuration (Web client ID and Web client secret) which can be found on
 * https://console.cloud.google.com/apis/credentials?project=<YOUR_PROJECT> under OAuth 2.0 Client IDs
 */
const signInPopup = async () => {
  try {
    const googleAuth = gapi.auth2.getAuthInstance()
    const googleUser = await googleAuth.signIn()

    const token = googleUser.getAuthResponse().id_token
    const credential = GoogleAuthProvider.credential(token)

    const response = await signInWithCredential(firebaseAuth, credential)

    // store user
  } catch (error) {
    // clean user from store
    console.error('signInPopup (firebase/auth.js)', error)
  }
}

const signOutUser = async () => {
  try {
    await gapi.auth2.getAuthInstance().signOut()
    console.log('User is signed out from gapi.')

    await signOut(firebaseAuth)
    console.log('User is signed out from firebase.')

    // clean user from store
  } catch (error) {
    console.error('signOutUser (firebase/auth.js): ', error)
  }
}

export { signInPopup, signOutUser }

However, you should be careful with this approach, since you will have to log out user from both services at once.

like image 139
Lazar Kulasevic Avatar answered Jun 29 '26 23:06

Lazar Kulasevic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!