如何从 Firebase 存储中删除图片?

3

我正在尝试将一个React Native项目适应新的Firebase方法。在这个项目中,我将图片上传到Storage并将它们添加到应用程序界面中。我还可以根据以下代码从界面中删除这些图像:

const removeImage = (img) => { // delete an image selected by the user
    Alert.alert(
      "Eliminar imagen",
      "¿Estás seguro de eliminar esta imagen?",
      [
        {
          text: "Cancelar",
          style: "cancel",
        },
        {
          text: "Eliminar",
          onPress: () => {
            const result = filter(
              formik.values.images,
              (image) => image !== img
            )
            formik.setFieldValue("images", result)
          },
        },
      ],
      { cancelable: false }
   

 ) 
  }

问题在于这种方式只会从我的应用程序中删除它们,而图像仍存储在 Firebase 中。 我的想法是,当我从前端删除图像时,它们也将从 Firebase 存储 中删除。

我已阅读 Firebase 文档,并且使用 deleteObject 函数可以实现这一点。

const storage = getStorage();

// Create a reference to the file to delete
const desertRef = ref(storage, 'images/desert.jpg');

// Delete the file
deleteObject(desertRef).then(() => {
  // File deleted successfully
}).catch((error) => {
  // Uh-oh, an error occurred!
})

我进行了一些测试,但无法使其正常工作。 我不知道该如何添加Firebase这里所示的指令.

我应该如何在我的代码中实现此函数以从存储中删除图像?

谢谢

import { getStorage, ref, deleteObject,  uploadBytes, getDownloadURL } from "firebase/storage"
export function UploadImagesForm(props) {
  const { formik } = props
  const [isLoading, setIsLoading] = useState(false) // status for loading

  // Function in charge of opening the image gallery
  const openGallery = async () => {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    })

    if (!result.cancelled) {
      // console.log('buscando imagenes')
      setIsLoading(true) // uploading the image
      uploadImage(result.uri)
    }
  }

  // function to upload the images to Firebase
  const uploadImage = async (uri) => {
    const response = await fetch(uri)
    const blob = await response.blob()

    const storage = getStorage()
    const storageRef = ref(storage, `restaurants/${uuid()}`)

    // we go to storage where we want to save the images
    uploadBytes(storageRef, blob).then((snapshot) => {
      // console.log(snapshot)
      updatePhotosRestaurant(snapshot.metadata.fullPath)
    })
  }

  // we take the URL in the previous function and set it in the state of the form
  const updatePhotosRestaurant = async (imagePath) => {
    const storage = getStorage()
    const imageRef = ref(storage, imagePath)


    const imageUrl = await getDownloadURL(imageRef) // get the url

    // code to upload all images without replacing them
    // get the current images and add the new ones with the array
    formik.setFieldValue("images", [...formik.values.images, imageUrl])

    setIsLoading(false)
  }

  const removeImage = (img) => { // delete an image selected by the user
    Alert.alert(
      "Eliminar imagen",
      "¿Estás seguro de eliminar esta imagen?",
      [
        {
          text: "Cancelar",
          style: "cancel",
        },
        {
          text: "Eliminar",
          onPress: () => {
            const result = filter(
              formik.values.images,
              (image) => image !== img
            )
            formik.setFieldValue("images", result)
          },
        },
      ],
      { cancelable: false }
    ) 
  }

  return (

    <>
      <ScrollView
        style={Styles.viewImage}
        horizontal
        showsHorizontalScrollIndicator={false}
      >
        <Icon
          type="material-community"
          name="camera"
          color="#a7a7a7"
          containerStyle={Styles.containerIcon}
          onPress={openGallery}
        />
        {map(formik.values.images, (image) => ( // display the images on the screen
          <Avatar
            key={image}
            source={{ uri: image }}
            containerStyle={Styles.imageStyle}
            onPress={() => removeImage(image)}
          />
        ))}
      </ScrollView>
      <Text style={Styles.error}>{formik.errors.images}</Text>
      <LoadingModal show={isLoading} text="Subiendo la imagen" />
    </>
  )
}

1
你需要做以下两步操作:1)创建一个对于想要从云存储中删除的图片的引用,2)将该引用传递给 deleteObject API。哪一步出现了问题? - Frank van Puffelen
我不知道如何做那个,@FrankvanPuffelen。我不知道引用图像的方式或代码。我不知道如何引用每个图像。我不知道如何创建引用,我感到困惑。 - Miguel Espeso
1
你已经在这里创建了一个图像引用:const storageRef = ref(storage, restaurants/${uuid()})。你需要创建一个类似的引用来删除你想要删除的图像。 - Frank van Puffelen
当然,问题在于我不知道如何引用每个图像。正如您所看到的,我从removeImage中删除它们,但我不明白如何同时从Firestore Storage中删除它们。我不知道在我的文件中如何或者在哪里放置这个功能。 - Miguel Espeso
3个回答

3
我终于弄清楚在我的文件中实现deleteObject函数的位置,使其正常工作。
您可以同时从应用程序和Firebase存储中删除图像。我找到了一位React专家来帮助我解决这个问题。
根据Firebase文档所述:
要删除文件,请先创建对该文件的引用。
const imageRef = ref(storage, img)
Firebase将其解释为:
import { getStorage, ref, deleteObject } from "firebase/storage";

const storage = getStorage();

// Create a reference to the file to delete
const desertRef = ref(storage, 'images/desert.jpg');

然后调用delete()方法(在我的情况下是deleteObject(imageRef))来删除该引用,它将返回一个解析的Promise或者如果Promise被拒绝,则返回一个错误。

import { getStorage, ref, deleteObject } from "firebase/storage";

const storage = getStorage();

// Create a reference to the file to delete
const desertRef = ref(storage, 'images/desert.jpg');

// Delete the file
deleteObject(desertRef).then(() => {
  // File deleted successfully
}).catch((error) => {
  // Uh-oh, an error occurred!
});

我希望这篇文章能帮助到其他像我一样正在学习Firebase的用户。
我展示了完整的代码文件,这样他们就不会像我一样有疑问,即Firebase方法应该放置在哪个正确的位置。
            const storage = getStorage()
            const imageRef = ref(storage, img)
            deleteObject(imageRef).then(() => { // also remove the image from Firebase
              console.log("la imagen se elimino");
            }).catch((error) => {
              console.log("ocurrio un error: ", error)
            })

感谢@FrankvanPuffelen和@BhavyaKoshiya的帮助。
import { getStorage, ref, uploadBytes, getDownloadURL, deleteObject } from 'firebase/storage'
import { v4 as uuid } from 'uuid'
import { map, filter } from 'lodash'

import { LoadingModal } from '../../Shared/LoadingModal/LoadingModal'
import Styles from './Styles'

export function UploadImagesForm(props) {
  
  const { formik } = props
  const [isLoading, setIsLoading] = useState(false) // status for loading

  // Function in charge of opening the image gallery
  const openGallery = async () => {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    })

    if (!result.cancelled) {
      // console.log('buscando imagenes')
      setIsLoading(true) // uploading the image
      uploadImage(result.uri)
    }
  }

  // function to upload the images to Firebase
  const uploadImage = async (uri) => {
    const response = await fetch(uri)
    const blob = await response.blob()

    const storage = getStorage()
    const storageRef = ref(storage, `restaurants/${uuid()}`)

    // we go to storage where we want to save the images
    uploadBytes(storageRef, blob).then((snapshot) => {
      // console.log(snapshot)
      updatePhotosRestaurant(snapshot.metadata.fullPath)
    })
  }

  // we take the URL in the previous function and set it in the state of the form
  const updatePhotosRestaurant = async (imagePath) => {
     const storage = getStorage()
    const imageRef = ref(storage, imagePath)


    const imageUrl = await getDownloadURL(imageRef) // get the url

    // code to upload all images without replacing them
    // get the current images and add the new ones with the array
    formik.setFieldValue("images", [...formik.values.images, imageUrl])

    setIsLoading(false)
  }

  const removeImage = (img) => { // delete an image selected by the user
    Alert.alert(
      "Eliminar imagen",
      "¿Estás seguro de eliminar esta imagen?",
      [
        {
          text: "Cancelar",
          style: "cancel",
        },
        {
          text: "Eliminar",
          onPress: async () => {
            const result = filter(
              formik.values.images,
              (image) => image !== img
            )
            formik.setFieldValue("images", result)

             **// THIS IS THE CODE I ADDED FROM FIREBASE**
            const storage = getStorage()
            const imageRef = ref(storage, img)
            deleteObject(imageRef).then(() => { // also remove the image from Firebase
              console.log("la imagen se elimino");
            }).catch((error) => {
              console.log("ocurrio un error: ", error)
            })
             **// END OF THE CODE I ADDED FROM FIREBASE**
          },
        },
      ],
      { cancelable: false }
    )
  }

1

非常好的解释!如果有人已经将ref URL存储在状态中,我在我的useImages钩子中添加了以下内容,它运行得很好。

const storage = getStorage(); 
const deleteImg = (refUrl) => { 
    const imageRef = ref(storage, refUrl)
    deleteObject(imageRef)
      .catch((error) => {
          console.log("Failed to delete image: ", error)
      })
}

0
你可以尝试这个。
let imageRef = storage.refFromURL(URL);
imageRef.delete()

感谢您的回答@BhavyaKoshiya,但我应该在哪里添加这个代码?我应该删除removeImage函数吗?我不知道该怎么做。我已经阅读了Firebase文档,但不知道如何将其实现到我的代码中。 - Miguel Espeso
2
在你的removeImage函数中加入"Yes",并提供该图片的URL。 - Bhavya Koshiya
这对我没用,@Bhavyakoshiya看看Firebase提出的方法是如何实现的,我不知道该如何实施。 这样做,它完美地工作了,应用程序和Firebase的图像都被删除了。 感谢你花时间帮助我。 - Miguel Espeso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接