How to upload an image to Supabase Storage in a React Native app using @supabase/supabase-js? Body

I am developing a React Native application using Expo and Supabase. I need to upload images to a Supabase Storage bucket. I am using Expo’s ImagePicker to select images, and I want to upload these images directly to Supabase Storage using the @supabase/supabase-js library.

Despite following various tutorials and examples, the image is not being uploaded to the bucket, and I receive no specific error messages to debug the issue. After selecting the image on my phone and clicking “Choose,” nothing happens—the image does not get uploaded, and no error is displayed.

I have ensured that my Supabase bucket policies allow public uploads and access.

Here is the current code for the upload functionality:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
SafeAreaView,
ScrollView,
Image,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { useNavigation, useRoute } from '@react-navigation/native';
import * as ImagePicker from 'expo-image-picker';
import { supabase } from '../database/supabaseClient';
import 'react-native-url-polyfill/auto';
import { Upload } from '@supabase/supabase-js';
const UploadSurpriseBagScreen = () => {
const navigation = useNavigation();
const route = useRoute();
const { userId } = route.params || {};
const [name, setName] = useState('');
const [bagNumber, setBagNumber] = useState('');
const [pickupHour, setPickupHour] = useState('');
const [validation, setValidation] = useState('');
const [price, setPrice] = useState('');
const [description, setDescription] = useState('');
const [category, setCategory] = useState('Breakfast');
const [imageUri, setImageUri] = useState('');
const [uploading, setUploading] = useState(false);
const pickImage = async () => {
const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (permissionResult.granted === false) {
alert("You've refused to allow this app to access your photos!");
return;
}
const pickerResult = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!pickerResult.cancelled) {
setImageUri(pickerResult.uri);
return pickerResult;
}
};
const uploadImage = async (uri) => {
try {
setUploading(true);
const response = await fetch(uri);
const blob = await response.blob();
const fileExt = uri.split('.').pop();
const fileName = `${Date.now()}.${fileExt}`;
const filePath = `${fileName}`;
const { data, error } = await supabase.storage.from('surprise_bags').upload(filePath, blob);
if (error) {
throw error;
}
const { publicURL, error: publicURLError } = await supabase.storage.from('surprise_bags').getPublicUrl(filePath);
if (publicURLError) {
throw publicURLError;
}
return publicURL;
} catch (error) {
console.error('Error uploading image:', error);
alert('Error uploading image');
return null;
} finally {
setUploading(false);
}
};
const handleUploadBag = async () => {
if (!name || !bagNumber || !pickupHour || !validation || !price || !description || !imageUri) {
alert('Please fill out all fields and upload an image');
return;
}
const imageUrl = await uploadImage(imageUri);
if (!imageUrl) return;
const { data: shop, error: shopError } = await supabase
.from('shops')
.select('id')
.eq('employee_id', userId)
.single();
if (shopError) {
console.error('Error fetching shop:', shopError);
alert('Error fetching shop information');
return;
}
const { error } = await supabase
.from('surprise_bags')
.insert([
{
employee_id: userId,
shop_id: shop.id,
name,
bag_number: bagNumber,
pickup_hour: pickupHour,
validation,
price,
description,
category,
image_url: imageUrl,
},
]);
if (error) {
console.error('Error uploading surprise bag:', error);
alert('Error uploading surprise bag');
} else {
alert('Surprise bag uploaded successfully');
navigation.goBack();
}
};
return (
<SafeAreaView style={styles.container}>
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}>
<Icon name="arrow-left" size={24} color="#000" />
</TouchableOpacity>
<ScrollView contentContainerStyle={styles.scrollContainer}>
<Text style={styles.headerTitle}>Upload Surprise Bags</Text>
<TouchableOpacity style={styles.uploadPhotoContainer} onPress={async () => {
const response = await pickImage();
if (response?.uri) {
setImageUri(response.uri);
}
}}>
{imageUri ? (
<Image source={{ uri: imageUri }} style={styles.uploadedImage} />
) : (
<>
<Icon name="image-outline" size={50} color="#82866b" />
<Text style={styles.uploadPhotoText}>Upload Photo</Text>
</>
)}
</TouchableOpacity>
<Text style={styles.label}>Name</Text>
<TextInput
style={styles.input}
placeholder="e.g. Surprise Bag"
value={name}
onChangeText={setName}
/>
<Text style={styles.label}>Bag no.</Text>
<TextInput
style={styles.input}
placeholder="e.g. #001"
value={bagNumber}
onChangeText={setBagNumber}
/>
<Text style={styles.label}>Pick up Hour</Text>
<TextInput
style={styles.input}
placeholder="e.g. 12:30pm - 4:30am"
value={pickupHour}
onChangeText={setPickupHour}
/>
<Text style={styles.label}>Validation</Text>
<TextInput
style={styles.input}
placeholder="e.g. 07/02/24 - 09/02/24"
value={validation}
onChangeText={setValidation}
/>
<Text style={styles.label}>Price</Text>
<TextInput
style={styles.input}
placeholder="e.g. $3.50"
value={price}
onChangeText={setPrice}
/>
<Text style={styles.label}>What you could get</Text>
<TextInput
style={styles.input}
placeholder="e.g. Lorem ipsum dolor sit amet consectetur."
value={description}
onChangeText={setDescription}
/>
<Text style={styles.label}>Food Category</Text>
<View style={styles.pickerContainer}>
<TouchableOpacity
onPress={() => setCategory('Breakfast')}
style={[styles.pickerButton, category === 'Breakfast' && styles.pickerButtonSelected]}
>
<Text style={styles.pickerButtonText}>Breakfast</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setCategory('Lunch')}
style={[styles.pickerButton, category === 'Lunch' && styles.pickerButtonSelected]}
>
<Text style={styles.pickerButtonText}>Lunch</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setCategory('Dinner')}
style={[styles.pickerButton, category === 'Dinner' && styles.pickerButtonSelected]}
>
<Text style={styles.pickerButtonText}>Dinner</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.uploadButton} onPress={handleUploadBag} disabled={uploading}>
<Text style={styles.uploadButtonText}>{uploading ? 'Uploading...' : 'Upload Bag'}</Text>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFFFFF',
},
backButton: {
marginTop: 10,
marginLeft: 10,
},
scrollContainer: {
paddingHorizontal: 20,
},
headerTitle: {
fontSize: 26,
fontWeight: 'bold',
textAlign: 'center',
marginTop: 30,
marginBottom: 20,
},
uploadPhotoContainer: {
borderColor: '#676a61',
borderWidth: 1,
borderStyle: 'dashed',
borderRadius: 10,
padding: 20,
alignItems: 'center',
marginBottom: 20,
},
uploadedImage: {
width: 100,
height: 100,
borderRadius: 10,
},
uploadPhotoText: {
fontSize: 16,
color: '#5c5f4c',
textAlign: 'center',
marginVertical: 10,
},
label: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 5,
color: '#5c5f4c',
},
input: {
borderWidth: 1,
borderColor: '#000',
paddingVertical: 8,
paddingHorizontal: 10,
borderRadius: 5,
marginBottom: 20,
height: 50,
},
pickerContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 20,
},
pickerButton: {
flex: 1,
paddingVertical: 10,
alignItems: 'center',
borderWidth: 1,
borderColor: '#000',
borderRadius: 5,
marginHorizontal: 5,
backgroundColor: '#fff',
},
pickerButtonSelected: {
backgroundColor: '#82866b',
},
pickerButtonText: {
color: '#5c5f4c',
},
uploadButton: {
backgroundColor: '#82866b',
paddingVertical: 12,
borderRadius: 5,
alignItems: 'center',
marginBottom: 20,
},
uploadButtonText: {
color: '#fff',
fontSize: 18,
fontWeight: 'bold',
},
});
export default UploadSurpriseBagScreen;
</code>
<code>import React, { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, SafeAreaView, ScrollView, Image, Alert, } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import { useNavigation, useRoute } from '@react-navigation/native'; import * as ImagePicker from 'expo-image-picker'; import { supabase } from '../database/supabaseClient'; import 'react-native-url-polyfill/auto'; import { Upload } from '@supabase/supabase-js'; const UploadSurpriseBagScreen = () => { const navigation = useNavigation(); const route = useRoute(); const { userId } = route.params || {}; const [name, setName] = useState(''); const [bagNumber, setBagNumber] = useState(''); const [pickupHour, setPickupHour] = useState(''); const [validation, setValidation] = useState(''); const [price, setPrice] = useState(''); const [description, setDescription] = useState(''); const [category, setCategory] = useState('Breakfast'); const [imageUri, setImageUri] = useState(''); const [uploading, setUploading] = useState(false); const pickImage = async () => { const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (permissionResult.granted === false) { alert("You've refused to allow this app to access your photos!"); return; } const pickerResult = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!pickerResult.cancelled) { setImageUri(pickerResult.uri); return pickerResult; } }; const uploadImage = async (uri) => { try { setUploading(true); const response = await fetch(uri); const blob = await response.blob(); const fileExt = uri.split('.').pop(); const fileName = `${Date.now()}.${fileExt}`; const filePath = `${fileName}`; const { data, error } = await supabase.storage.from('surprise_bags').upload(filePath, blob); if (error) { throw error; } const { publicURL, error: publicURLError } = await supabase.storage.from('surprise_bags').getPublicUrl(filePath); if (publicURLError) { throw publicURLError; } return publicURL; } catch (error) { console.error('Error uploading image:', error); alert('Error uploading image'); return null; } finally { setUploading(false); } }; const handleUploadBag = async () => { if (!name || !bagNumber || !pickupHour || !validation || !price || !description || !imageUri) { alert('Please fill out all fields and upload an image'); return; } const imageUrl = await uploadImage(imageUri); if (!imageUrl) return; const { data: shop, error: shopError } = await supabase .from('shops') .select('id') .eq('employee_id', userId) .single(); if (shopError) { console.error('Error fetching shop:', shopError); alert('Error fetching shop information'); return; } const { error } = await supabase .from('surprise_bags') .insert([ { employee_id: userId, shop_id: shop.id, name, bag_number: bagNumber, pickup_hour: pickupHour, validation, price, description, category, image_url: imageUrl, }, ]); if (error) { console.error('Error uploading surprise bag:', error); alert('Error uploading surprise bag'); } else { alert('Surprise bag uploaded successfully'); navigation.goBack(); } }; return ( <SafeAreaView style={styles.container}> <TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}> <Icon name="arrow-left" size={24} color="#000" /> </TouchableOpacity> <ScrollView contentContainerStyle={styles.scrollContainer}> <Text style={styles.headerTitle}>Upload Surprise Bags</Text> <TouchableOpacity style={styles.uploadPhotoContainer} onPress={async () => { const response = await pickImage(); if (response?.uri) { setImageUri(response.uri); } }}> {imageUri ? ( <Image source={{ uri: imageUri }} style={styles.uploadedImage} /> ) : ( <> <Icon name="image-outline" size={50} color="#82866b" /> <Text style={styles.uploadPhotoText}>Upload Photo</Text> </> )} </TouchableOpacity> <Text style={styles.label}>Name</Text> <TextInput style={styles.input} placeholder="e.g. Surprise Bag" value={name} onChangeText={setName} /> <Text style={styles.label}>Bag no.</Text> <TextInput style={styles.input} placeholder="e.g. #001" value={bagNumber} onChangeText={setBagNumber} /> <Text style={styles.label}>Pick up Hour</Text> <TextInput style={styles.input} placeholder="e.g. 12:30pm - 4:30am" value={pickupHour} onChangeText={setPickupHour} /> <Text style={styles.label}>Validation</Text> <TextInput style={styles.input} placeholder="e.g. 07/02/24 - 09/02/24" value={validation} onChangeText={setValidation} /> <Text style={styles.label}>Price</Text> <TextInput style={styles.input} placeholder="e.g. $3.50" value={price} onChangeText={setPrice} /> <Text style={styles.label}>What you could get</Text> <TextInput style={styles.input} placeholder="e.g. Lorem ipsum dolor sit amet consectetur." value={description} onChangeText={setDescription} /> <Text style={styles.label}>Food Category</Text> <View style={styles.pickerContainer}> <TouchableOpacity onPress={() => setCategory('Breakfast')} style={[styles.pickerButton, category === 'Breakfast' && styles.pickerButtonSelected]} > <Text style={styles.pickerButtonText}>Breakfast</Text> </TouchableOpacity> <TouchableOpacity onPress={() => setCategory('Lunch')} style={[styles.pickerButton, category === 'Lunch' && styles.pickerButtonSelected]} > <Text style={styles.pickerButtonText}>Lunch</Text> </TouchableOpacity> <TouchableOpacity onPress={() => setCategory('Dinner')} style={[styles.pickerButton, category === 'Dinner' && styles.pickerButtonSelected]} > <Text style={styles.pickerButtonText}>Dinner</Text> </TouchableOpacity> </View> <TouchableOpacity style={styles.uploadButton} onPress={handleUploadBag} disabled={uploading}> <Text style={styles.uploadButtonText}>{uploading ? 'Uploading...' : 'Upload Bag'}</Text> </TouchableOpacity> </ScrollView> </SafeAreaView> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#FFFFFF', }, backButton: { marginTop: 10, marginLeft: 10, }, scrollContainer: { paddingHorizontal: 20, }, headerTitle: { fontSize: 26, fontWeight: 'bold', textAlign: 'center', marginTop: 30, marginBottom: 20, }, uploadPhotoContainer: { borderColor: '#676a61', borderWidth: 1, borderStyle: 'dashed', borderRadius: 10, padding: 20, alignItems: 'center', marginBottom: 20, }, uploadedImage: { width: 100, height: 100, borderRadius: 10, }, uploadPhotoText: { fontSize: 16, color: '#5c5f4c', textAlign: 'center', marginVertical: 10, }, label: { fontSize: 16, fontWeight: 'bold', marginBottom: 5, color: '#5c5f4c', }, input: { borderWidth: 1, borderColor: '#000', paddingVertical: 8, paddingHorizontal: 10, borderRadius: 5, marginBottom: 20, height: 50, }, pickerContainer: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20, }, pickerButton: { flex: 1, paddingVertical: 10, alignItems: 'center', borderWidth: 1, borderColor: '#000', borderRadius: 5, marginHorizontal: 5, backgroundColor: '#fff', }, pickerButtonSelected: { backgroundColor: '#82866b', }, pickerButtonText: { color: '#5c5f4c', }, uploadButton: { backgroundColor: '#82866b', paddingVertical: 12, borderRadius: 5, alignItems: 'center', marginBottom: 20, }, uploadButtonText: { color: '#fff', fontSize: 18, fontWeight: 'bold', }, }); export default UploadSurpriseBagScreen; </code>
import React, { useState } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  StyleSheet,
  SafeAreaView,
  ScrollView,
  Image,
  Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { useNavigation, useRoute } from '@react-navigation/native';
import * as ImagePicker from 'expo-image-picker';
import { supabase } from '../database/supabaseClient';
import 'react-native-url-polyfill/auto';
import { Upload } from '@supabase/supabase-js';

const UploadSurpriseBagScreen = () => {
  const navigation = useNavigation();
  const route = useRoute();
  const { userId } = route.params || {};

  const [name, setName] = useState('');
  const [bagNumber, setBagNumber] = useState('');
  const [pickupHour, setPickupHour] = useState('');
  const [validation, setValidation] = useState('');
  const [price, setPrice] = useState('');
  const [description, setDescription] = useState('');
  const [category, setCategory] = useState('Breakfast');
  const [imageUri, setImageUri] = useState('');
  const [uploading, setUploading] = useState(false);

  const pickImage = async () => {
    const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this app to access your photos!");
      return;
    }

    const pickerResult = await ImagePicker.launchImageLibraryAsync({
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    if (!pickerResult.cancelled) {
      setImageUri(pickerResult.uri);
      return pickerResult;
    }
  };

  const uploadImage = async (uri) => {
    try {
      setUploading(true);
      const response = await fetch(uri);
      const blob = await response.blob();
      const fileExt = uri.split('.').pop();
      const fileName = `${Date.now()}.${fileExt}`;
      const filePath = `${fileName}`;

      const { data, error } = await supabase.storage.from('surprise_bags').upload(filePath, blob);

      if (error) {
        throw error;
      }

      const { publicURL, error: publicURLError } = await supabase.storage.from('surprise_bags').getPublicUrl(filePath);

      if (publicURLError) {
        throw publicURLError;
      }

      return publicURL;
    } catch (error) {
      console.error('Error uploading image:', error);
      alert('Error uploading image');
      return null;
    } finally {
      setUploading(false);
    }
  };

  const handleUploadBag = async () => {
    if (!name || !bagNumber || !pickupHour || !validation || !price || !description || !imageUri) {
      alert('Please fill out all fields and upload an image');
      return;
    }

    const imageUrl = await uploadImage(imageUri);

    if (!imageUrl) return;

    const { data: shop, error: shopError } = await supabase
      .from('shops')
      .select('id')
      .eq('employee_id', userId)
      .single();

    if (shopError) {
      console.error('Error fetching shop:', shopError);
      alert('Error fetching shop information');
      return;
    }

    const { error } = await supabase
      .from('surprise_bags')
      .insert([
        {
          employee_id: userId,
          shop_id: shop.id,
          name,
          bag_number: bagNumber,
          pickup_hour: pickupHour,
          validation,
          price,
          description,
          category,
          image_url: imageUrl,
        },
      ]);

    if (error) {
      console.error('Error uploading surprise bag:', error);
      alert('Error uploading surprise bag');
    } else {
      alert('Surprise bag uploaded successfully');
      navigation.goBack();
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      <TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}>
        <Icon name="arrow-left" size={24} color="#000" />
      </TouchableOpacity>
      <ScrollView contentContainerStyle={styles.scrollContainer}>
        <Text style={styles.headerTitle}>Upload Surprise Bags</Text>
        <TouchableOpacity style={styles.uploadPhotoContainer} onPress={async () => {
          const response = await pickImage();
          if (response?.uri) {
            setImageUri(response.uri);
          }
        }}>
          {imageUri ? (
            <Image source={{ uri: imageUri }} style={styles.uploadedImage} />
          ) : (
            <>
              <Icon name="image-outline" size={50} color="#82866b" />
              <Text style={styles.uploadPhotoText}>Upload Photo</Text>
            </>
          )}
        </TouchableOpacity>

        <Text style={styles.label}>Name</Text>
        <TextInput
          style={styles.input}
          placeholder="e.g. Surprise Bag"
          value={name}
          onChangeText={setName}
        />

        <Text style={styles.label}>Bag no.</Text>
        <TextInput
          style={styles.input}
          placeholder="e.g. #001"
          value={bagNumber}
          onChangeText={setBagNumber}
        />

        <Text style={styles.label}>Pick up Hour</Text>
        <TextInput
          style={styles.input}
          placeholder="e.g. 12:30pm - 4:30am"
          value={pickupHour}
          onChangeText={setPickupHour}
        />

        <Text style={styles.label}>Validation</Text>
        <TextInput
          style={styles.input}
          placeholder="e.g. 07/02/24 - 09/02/24"
          value={validation}
          onChangeText={setValidation}
        />

        <Text style={styles.label}>Price</Text>
        <TextInput
          style={styles.input}
          placeholder="e.g. $3.50"
          value={price}
          onChangeText={setPrice}
        />

        <Text style={styles.label}>What you could get</Text>
        <TextInput
          style={styles.input}
          placeholder="e.g. Lorem ipsum dolor sit amet consectetur."
          value={description}
          onChangeText={setDescription}
        />

        <Text style={styles.label}>Food Category</Text>
        <View style={styles.pickerContainer}>
          <TouchableOpacity
            onPress={() => setCategory('Breakfast')}
            style={[styles.pickerButton, category === 'Breakfast' && styles.pickerButtonSelected]}
          >
            <Text style={styles.pickerButtonText}>Breakfast</Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => setCategory('Lunch')}
            style={[styles.pickerButton, category === 'Lunch' && styles.pickerButtonSelected]}
          >
            <Text style={styles.pickerButtonText}>Lunch</Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => setCategory('Dinner')}
            style={[styles.pickerButton, category === 'Dinner' && styles.pickerButtonSelected]}
          >
            <Text style={styles.pickerButtonText}>Dinner</Text>
          </TouchableOpacity>
        </View>

        <TouchableOpacity style={styles.uploadButton} onPress={handleUploadBag} disabled={uploading}>
          <Text style={styles.uploadButtonText}>{uploading ? 'Uploading...' : 'Upload Bag'}</Text>
        </TouchableOpacity>
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#FFFFFF',
  },
  backButton: {
    marginTop: 10,
    marginLeft: 10,
  },
  scrollContainer: {
    paddingHorizontal: 20,
  },
  headerTitle: {
    fontSize: 26,
    fontWeight: 'bold',
    textAlign: 'center',
    marginTop: 30,
    marginBottom: 20,
  },
  uploadPhotoContainer: {
    borderColor: '#676a61',
    borderWidth: 1,
    borderStyle: 'dashed',
    borderRadius: 10,
    padding: 20,
    alignItems: 'center',
    marginBottom: 20,
  },
  uploadedImage: {
    width: 100,
    height: 100,
    borderRadius: 10,
  },
    uploadPhotoText: {
    fontSize: 16,
    color: '#5c5f4c',
    textAlign: 'center',
    marginVertical: 10,
  },
  label: {
    fontSize: 16,
    fontWeight: 'bold',
    marginBottom: 5,
    color: '#5c5f4c',
  },
  input: {
    borderWidth: 1,
    borderColor: '#000',
    paddingVertical: 8,
    paddingHorizontal: 10,
    borderRadius: 5,
    marginBottom: 20,
    height: 50,
  },
  pickerContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 20,
  },
  pickerButton: {
    flex: 1,
    paddingVertical: 10,
    alignItems: 'center',
    borderWidth: 1,
    borderColor: '#000',
    borderRadius: 5,
    marginHorizontal: 5,
    backgroundColor: '#fff',
  },
  pickerButtonSelected: {
    backgroundColor: '#82866b',
  },
  pickerButtonText: {
    color: '#5c5f4c',
  },
  uploadButton: {
    backgroundColor: '#82866b',
    paddingVertical: 12,
    borderRadius: 5,
    alignItems: 'center',
    marginBottom: 20,
  },
  uploadButtonText: {
    color: '#fff',
    fontSize: 18,
    fontWeight: 'bold',
  },
});

export default UploadSurpriseBagScreen;


And i used the following policies:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE POLICY "Anyone can upload to surprise_bags"
ON storage.objects
FOR INSERT
WITH CHECK (bucket_id = 'surprise_bags');
</code>
<code>CREATE POLICY "Anyone can upload to surprise_bags" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'surprise_bags'); </code>
CREATE POLICY "Anyone can upload to surprise_bags" 
ON storage.objects
FOR INSERT
WITH CHECK (bucket_id = 'surprise_bags');

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE POLICY "Anyone can update surprise_bags"
ON storage.objects
FOR UPDATE
USING (bucket_id = 'surprise_bags')
WITH CHECK (bucket_id = 'surprise_bags');
</code>
<code>CREATE POLICY "Anyone can update surprise_bags" ON storage.objects FOR UPDATE USING (bucket_id = 'surprise_bags') WITH CHECK (bucket_id = 'surprise_bags'); </code>
CREATE POLICY "Anyone can update surprise_bags" 
ON storage.objects
FOR UPDATE
USING (bucket_id = 'surprise_bags')
WITH CHECK (bucket_id = 'surprise_bags');

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>CREATE POLICY "Anyone can view surprise_bags"
ON storage.objects
FOR SELECT
USING (bucket_id = 'surprise_bags');
</code>
<code>CREATE POLICY "Anyone can view surprise_bags" ON storage.objects FOR SELECT USING (bucket_id = 'surprise_bags'); </code>
CREATE POLICY "Anyone can view surprise_bags" 
ON storage.objects
FOR SELECT
USING (bucket_id = 'surprise_bags');

New contributor

Abdelhak Abdelkader kheddaoui is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật