Saturday, June 15, 2024
Ana SayfaCosmic Meta QAProgramming QuestionsResolving Google Sign-In Integration Issues in React Native and Node.js

Resolving Google Sign-In Integration Issues in React Native and Node.js

QUESTION:

I’m creating an app with React Native and Node.js. I already have my auth system. Now I try to implement Google Sign-In. So far, I’ve:

  1. Created a Google application in Firebase.
  2. Generated the .keystore file and obtained the SHA1 key.
  3. Updated the build.gradle to install the SDK on the client.
  4. Placed the file in the client and the Google service file in my Node.js app.
  5. Implemented the code in React Native and Node.js.
  6. Retrieved the token from the client.

However, I encountered an error while testing with Postman. The error message is:

“Firebase ID token has incorrect ‘aud’ (audience) claim. Expected ‘tak-muscu’ but got ‘XXXX-ruib6t1s7lochabens3f3ep67pa411nc.apps.googleusercontent.com’. Make sure the ID token comes from the same Firebase project as the service account used to authenticate this SDK. See Firebase documentation for details on how to retrieve an ID token.”

Here is my code:

React Native (Client Side):

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

GoogleSignin.configure({
  webClientId: 'XXXXX-ruib6t1s7lochabens3f3ep67pa411nc.apps.googleusercontent.com',
  androidClientId: 'XXXXX-fvv7nndd0q53hvoht9cldt82jm5a9306.apps.googleusercontent.com',
  scopes: ['profile', 'email'],
});

const signIn = async () => {
  try {
    await GoogleSignin.hasPlayServices();
    const userInfo = await GoogleSignin.signIn();
    const idToken = userInfo.idToken;
    console.log('ID Token:', idToken);
  } catch (error) {
    console.error('Google Sign-In error', error.message);
  }
};

Express Route (Server Side):

const express = require('express');
const router = express.Router();
const { verifyGoogleToken } = require('./verifyGoogleToken');

router.post('/google-signin', async (req, res) => {
  const { idToken } = req.body;
  const result = await verifyGoogleToken(idToken);
  if (result.status === 'success') {
    res.send({ message: 'Authentication successful', user: result.decodedToken });
  } else {
    res.status(401).send({ message: 'Authentication failed', error: result.message });
  }
});

module.exports = router;

Verify Google Token Function:

const admin = require('firebase-admin');

const verifyGoogleToken = async (idToken) => {
  try {
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    console.log("Token validated successfully", decodedToken);
    return { status: 'success', uid: decodedToken.uid };
  } catch (error) {
    console.error('Error verifying token', error);
    return { status: 'error', message: error.message };
  }
};

module.exports = { verifyGoogleToken };

App.js Server Initialization:

const admin = require('firebase-admin');
const serviceAccount = require('./secrets/service-account-file.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

I tried it 4 times and I get the same error every time. How can I resolve this issue?

ANSWER:

Understanding the Error

The error message you are encountering, “Firebase ID token has incorrect ‘aud’ (audience) claim,” indicates that the ID token’s audience claim does not match the expected value. This usually happens when the token is generated using a different Firebase project than the one your server is using to verify the token.

Steps to Resolve the Issue

Step 1: Verify Firebase Project Configuration

Ensure that the Firebase project used to generate the ID token in your React Native app is the same as the one used in your Node.js backend for verification.

  1. Firebase Console: Go to the Firebase console and open the project you are working on.
  2. Project Settings: Navigate to Project Settings and verify the project_id, webClientId, and androidClientId.
  3. Service Account: Ensure that the service account file used in your Node.js app belongs to the same Firebase project.

Step 2: Update Firebase Configuration in React Native

Make sure that the webClientId and androidClientId in your GoogleSignin.configure method match the client IDs listed in your Firebase project settings.

React Native (Client Side):

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

GoogleSignin.configure({
  webClientId: 'YOUR_CORRECT_WEB_CLIENT_ID.apps.googleusercontent.com',
  androidClientId: 'YOUR_CORRECT_ANDROID_CLIENT_ID.apps.googleusercontent.com',
  scopes: ['profile', 'email'],
});

const signIn = async () => {
  try {
    await GoogleSignin.hasPlayServices();
    const userInfo = await GoogleSignin.signIn();
    const idToken = userInfo.idToken;
    console.log('ID Token:', idToken);
  } catch (error) {
    console.error('Google Sign-In error', error.message);
  }
};

Step 3: Verify Token on the Server

Ensure your server is correctly set up to verify the ID token using the Firebase Admin SDK.

Express Route (Server Side):

const express = require('express');
const router = express.Router();
const { verifyGoogleToken } = require('./verifyGoogleToken');

router.post('/google-signin', async (req, res) => {
  const { idToken } = req.body;
  const result = await verifyGoogleToken(idToken);
  if (result.status === 'success') {
    res.send({ message: 'Authentication successful', user: result.decodedToken });
  } else {
    res.status(401).send({ message: 'Authentication failed', error: result.message });
  }
});

module.exports = router;

Verify Google Token Function:

const admin = require('firebase-admin');

const verifyGoogleToken = async (idToken) => {
  try {
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    console.log("Token validated successfully", decodedToken);
    return { status: 'success', decodedToken };
  } catch (error) {
    console.error('Error verifying token', error);
    return { status: 'error', message: error.message };
  }
};

module.exports = { verifyGoogleToken };

Step 4: Ensure Consistent Environment Setup

  1. Check Environment Variables: Ensure your environment variables and configurations are consistent across your development and production environments.
  2. SHA1 Key: Make sure the SHA1 key used in the Firebase project settings matches the one used to generate the .keystore file.

Example Code for Correct Setup

Here is an example of the correct setup for your React Native app and Node.js backend:

React Native (Client Side):

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

GoogleSignin.configure({
  webClientId: 'YOUR_CORRECT_WEB_CLIENT_ID.apps.googleusercontent.com',
  androidClientId: 'YOUR_CORRECT_ANDROID_CLIENT_ID.apps.googleusercontent.com',
  scopes: ['profile', 'email'],
});

const signIn = async () => {
  try {
    await GoogleSignin.hasPlayServices();
    const userInfo = await GoogleSignin.signIn();
    const idToken = userInfo.idToken;
    console.log('ID Token:', idToken);
  } catch (error) {
    console.error('Google Sign-In error', error.message);
  }
};

Express Route (Server Side):

const express = require('express');
const router = express.Router();
const { verifyGoogleToken } = require('./verifyGoogleToken');

router.post('/google-signin', async (req, res) => {
  const { idToken } = req.body;
  const result = await verifyGoogleToken(idToken);
  if (result.status === 'success') {
    res.send({ message: 'Authentication successful', user: result.decodedToken });
  } else {
    res.status(401).send({ message: 'Authentication failed', error: result.message });
  }
});

module.exports = router;

Verify Google Token Function:

const admin = require('firebase-admin');

const verifyGoogleToken = async (idToken) => {
  try {
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    console.log("Token validated successfully", decodedToken);
    return

 { status: 'success', decodedToken };
  } catch (error) {
    console.error('Error verifying token', error);
    return { status: 'error', message: error.message };
  }
};

module.exports = { verifyGoogleToken };

App.js Server Initialization:

const admin = require('firebase-admin');
const serviceAccount = require('./secrets/service-account-file.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

Additional Resources

For further reading and troubleshooting, refer to the following resources:

Cosmic Meta
Cosmic Metahttps://cosmicmeta.io
Cosmic Meta Digital is your ultimate destination for the latest tech news, in-depth reviews, and expert analyses. Our mission is to keep you informed and ahead of the curve in the rapidly evolving world of technology, covering everything from programming best practices to emerging tech trends. Join us as we explore and demystify the digital age.
RELATED ARTICLES

CEVAP VER

Lütfen yorumunuzu giriniz!
Lütfen isminizi buraya giriniz

- Advertisment -

Most Popular

Recent Comments