React Native

Delete Files from a React Native App

Introduction

In this guide, you will learn the best way to delete files from back4app cloud in React Native Apps.

For managing application files in Back4app, we use the Parse.File utility class. You can perform storing, retrieving, and deleting operations using this class. In the previous section, File Storage, we covered storing and retrieving files by creating a demo gallery App.

At this point, you should be aware that after creating and saving a Parse.File, the best practice is to always associate it with another data object. It will prevent the creation of orphan files in your project and make it possible for you to find and delete them on Back4app cloud.

Parse.File provides a way of deleting files, but it is a security sensitive operation that you should not perform on client-side. In this tutorial, you will learn the best practice for removing your application files.

Goal

Add delete image action to a React Native gallery demo App

Prerequisites

To complete this tutorial, you will need:

Step 1 - Application setup

In the previous section, File Storage, we built a demo gallery App to upload and display user pictures.
For this tutorial, You will increment this App by adding a delete button to each image item in the Gallery.js component and performing our delete operation.

If you already finished coding the demo gallery App then you can jump to the next step.

Alternatively, you can clone the code base for the App to follow this tutorial along.

To clone the project run:

git clone https://github.com/templates-back4app/react-native-demo-gallery-app

Then, install project dependencies:

1
2
3
4
5
6
7
cd react-native-demo-gallery-app

# using yarn
yarn install

# using npm
npm install

Before running, remember to setup your Back4app credentials, App Id and JavascriptKey, on the initialize method. For information on App credentials setup see Install Parse SDK.

Finally, run the React Native Application:

1
2
3
4
5
# For Android
npx react-native run-android

# For iOS
npx react-native run-ios

Step 2 - Creating a delete button

On the gallery App, the Gallery.js component renders the list of images from your Back4app cloud project. Next, you will create and add a button to every image item in the current list.

Open the Gallery.js file add the following content:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import React, {useState, useEffect} from  'react';
import {Text, View, Image, FlatList, StyleSheet, Button, Alert} from  'react-native';
import Parse from  'parse/react-native.js';

const Gallery = () => {
const [images, setImages] = useState([]);

useEffect(() => {
  const fetchImages = async () => {
  let query = new Parse.Query('Gallery');
  const results = await  query.find();
  setImages(results);
  };

  fetchImages();
}, []);

async function onDeleteImage(image_id) {
  // TODO: implement this function
}

return (
<FlatList
  style={styles.container}
  contentContainerStyle={styles.listContent}
  data={images}
  horizontal={false}
  numColumns={3}
  ListEmptyComponent={() =>  <Text>No images uploaded.</Text>}
  renderItem={({item}) => (
    <View>
      <Image
        source={ {uri: item.get('picture').url()} }
        style={styles.imageItem}
      />
     <Button
        title="Delete"
        color="red"
        onPress={() => onDeleteImage(item.id)}
      />
    </View>
  )}
  keyExtractor={(item) =>  item.id}
/>);

};

const styles = StyleSheet.create({
container: {
  flex: 1,
  backgroundColor: '#f5f5f5',
},
listContent: {
  justifyContent: 'center',
  alignItems: 'center',
},
imageItem: {
  width: 100,
  height: 100,
  resizeMode: 'cover',
  marginHorizontal: 5,
  marginVertical: 5,
},
});
export default Gallery;

We have refactored the renderItem function, including a delete button to all rendered images. However, the button click event still has no functionality implemented. You will do it on the next step.

Step 3 - Creating a delete picture cloud function

You’ve learned that a file should always be associated with a data object on the File Storage. Not associating files to data objects will result in orphan files. Those files are unreachable inside your App. Once you can’t find them, you also can’t delete them from your App. You can only erase them using the Purge Files option on Back4App Dashboard.

The deleting process consists of finding and then deleting it. In Parse, the destroy method is used to delete referenced files. However, using it on client side is not safe as it requires the masterKey.

When you build a React Native app, all your keys are bundled together, therefore, anyone could reverse engineer, decompile your app or proxy your network traffic from their device to find your masterKey. Using the master key allows you to bypass all of your app’s security mechanisms, such as class-level permissions and ACLs. You can find more details about Parse security best practices here.

The best way to delete files is to do it on the server side using a Cloud Code function. In our gallery app, we will create a cloud code function for that.

Let’s create a main.js file with the following cloud function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Parse.Cloud.define('deleteGalleryPicture', async (request) => {
	const {image_id} = request.params;
	const Gallery = Parse.Object.extend('Gallery');
	const query = new Parse.Query(Gallery);
	try {
		const Image = await query.get(image_id);
		const picture = Image.get('picture');

		await picture.destroy({useMasterKey:  true});
		await Image.destroy();
		return 'Image removed.';
	} catch (error) {
		console.log(error);
		throw new Error('Error deleting image');
	}
});

For simplicity, we will use the Dashboard to upload cloud functions directly:

  1. Open your App Dashboard at Back4App Website and click on Core, then Cloud Code Functions.
  2. Upload main.js file on the root of the cloud/ folder.
  3. Deploy the function to Back4app server

React Native Back4App

After a few seconds your cloud code function will be available to be called via REST or Parse SDK.

React Native Back4App

Step 4 - Calling delete cloud function from your App

Once you have successfully deployed your Back4app Cloud Code function, go ahead and implement the action for when the users presses delete button in our gallery app:

1
2
3
4
5
6
7
8
9
10
11
// Triggers on hitting delete
async function onDeleteImage(image_id) {
  try {
    const params = {image_id};
    const result = await Parse.Cloud.run('deleteGalleryPicture', params);
    Alert.alert(result);
  } catch (error) {
    console.log('Delete Error: ', error);
  }
}

Now when you click on delete, your app will trigger deleteGalleryPicture cloud function that will successfully delete an image:

React Native Back4App

Step 5 - Purging Files

In some situations, when you lost track of your application files you need to delete files from your Dashboard. This usually occurs when you create the orphan files mentioned in this article.

For information on how to clean up your application files:

  1. Try Back4app Files common questions
  2. Or See App Settings documentation

Done!

At this point, you have succefully deployed a cloud code function and learned how to delete an image in a React Native application.