I’m working on a React Native Expo project and need to connect to Google Drive API using a service account. My goal is to read files from a specific folder in Google Drive without requiring user login.
I’ve already set up a Google service account with editor permissions and shared the target folder with this account. I’m using Expo development build rather than Expo Go.
I keep running into issues when trying to implement the authentication. I’ve tried using the ‘google-auth-library’ package but I get a “prototype may only be an Object or null: undefined” error when testing in the browser. The error only appears when I include the authentication code.
The Expo docs point to “@react-native-google-signin/google-signin” but that seems designed for user authentication, not service accounts.
Here’s my current implementation:
import { Constants } from 'expo-constants';
import { GoogleAuth } from 'google-auth-library';
import fetch from 'axios';
// Get service account details from configuration
const {
PROJECT_ID,
SERVICE_EMAIL,
PRIVATE_KEY_DATA,
KEY_ID,
CLIENT_IDENTIFIER,
} = Constants.expoConfig?.extra || {};
// Format private key to handle escaped characters
const formattedPrivateKey = PRIVATE_KEY_DATA.replace(/\\n/g, '\n');
/**
* Function to authenticate with Google Drive API and get access token
* @returns {Promise<string>} Access token for API calls
*/
export const getGoogleDriveToken = async (): Promise<string> => {
try {
if (!SERVICE_EMAIL || !PRIVATE_KEY_DATA || !PROJECT_ID) {
throw new Error('Service account configuration missing');
}
console.log("Initializing GoogleAuth");
console.log("Service Email: ", SERVICE_EMAIL);
console.log("Private Key: ", formattedPrivateKey);
console.log("Project ID: ", PROJECT_ID);
// Create authentication object with service account credentials
const googleAuth = new GoogleAuth({
credentials: {
type: 'service_account',
project_id: PROJECT_ID,
private_key: formattedPrivateKey,
client_email: SERVICE_EMAIL,
},
scopes: ['https://www.googleapis.com/auth/drive'],
});
const authClient = await googleAuth.getClient();
const accessToken = await authClient.getAccessToken();
if (!accessToken.token) {
throw new Error('Failed to retrieve access token');
}
return accessToken.token;
} catch (error) {
console.error('Google authentication error:', error);
throw error;
}
};
How can I properly authenticate with Google Drive API using a service account in Expo? Any suggestions for alternative approaches would be helpful.