Skip to main content

Configure Google Drive API

caution

Please note that filenames are not unique in Google Drive. There can be multiple files with the same name within the same directory (even files and directories sharing the same name). By default, the library will not throw any errors when there are multiple files with the same name detected, but instead default to the first file found. However, this might be problematic when working with the CloudStorage.Documents scope. Please see here for more info.

info

Be aware that all file operations on Google Drive will take severely more time than on iCloud. This is because iCloud is implemented using a direct native API (CloudKit) while Google Drive is implemented using the HTTP REST API. A file read operation that might only take a split second on iCloud might take several seconds on Google Drive.

While iCloud for iOS devices works out of the box, Google Drive support requires some additional setup. Specifically, you will need to get and provide an access token for the Google Drive API. This module does not provide any way of acquiring such a token from the user, as it is out of scope.

You therefore need to acquire the token with another library. Popular choices are @react-native-google-signin/google-signin and expo-auth-session. Whatever you do, you will also need a Google OAuth client ID in order to make authentication requests. The linked Expo module has good documentation on this topic. When creating this client ID, make sure to request at least the https://www.googleapis.com/auth/drive.appdata scope. This will allow you to use the CloudStorageScope.AppData scope of this library. If you also want to access CloudStorageScope.Documents, you will also require the https://www.googleapis.com/auth/drive scope, which is a restricted Google API scope. This means your app needs to be audited in order to use it. For more documentation on this matter, consult the Google documentation.

Once you have acquired an access token from the user, you will need to provide it to the library:

import { CloudStorage } from 'react-native-cloud-storage';
CloudStorage.setGoogleDriveAccessToken(accessToken);

The access token is stored globally / statically so that it is valid across the project.

Below is a more practical example of how this could look in action using the Expo AuthSession API:

import { useEffect, useState } from 'react';
import { StyleSheet, Text, View, Button, Platform } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import * as Google from 'expo-auth-session/providers/google';
import { CloudStorage, CloudStorageScope } from 'react-native-cloud-storage';

WebBrowser.maybeCompleteAuthSession();

const App: React.FC = () => {
const [accessToken, setAccessToken] = useState<string | null>(null);

const [request, response, promptAsync] = Google.useAuthRequest({
androidClientId: 'GOOGLE_GUID.apps.googleusercontent.com',
scopes: ['https://www.googleapis.com/auth/drive.appdata'],
});

useEffect(() => {
if (response?.type === 'success') {
setAccessToken(response.authentication.accessToken);
}

if (accessToken) {
CloudStorage.setGoogleDriveAccessToken(accessToken);
}
}, [response, accessToken]);

const writeFileAsync = () => {
return CloudStorage.writeFile('test.txt', 'Hello World', CloudStorageScope.AppData);
};

return (
<View style={styles.container}>
{Platform.OS === 'android' && accessToken === null ? (
<Button
title="Sign in with Google"
disabled={!request}
onPress={() => {
promptAsync();
}}
/>
) : (
<Button
title="Write Hello World to test.txt"
onPress={() => {
writeFileAsync();
}}
/>
)}
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 20,
fontWeight: 'bold',
},
});

In the end, you are responsible for acquiring and potentially refreshing the access token. Do note however, that this process does not need to be done for iOS as iOS will not use the Google Drive REST API but instead fully rely on CloudKit / iCloud.