Acceso

Subida de archivos a Firebase Storage.

toscadev

@ ToscaDevsJS


Storage ofrece una solución sólida para almacenar y acceder a archivos en la nube de manera eficiente.


npm install react-hot-toast

npm install firebase

CÓDIGO COMPLETO

Este fragmento de código simplifica la tarea de cargar archivos en Firebase Storage desde aplicaciones React y proporciona una forma eficiente de manejar la interacción con archivos seleccionados por el usuario.

addFileStorage.ts

import { storage } from "@/context/firebase-config";
import { FirebaseError } from "firebase/app";
import { deleteObject } from "firebase/storage";
import {
  getDownloadURL,
  ref,
  uploadBytes,
  uploadBytesResumable,
} from "firebase/storage";
import toast from "react-hot-toast";

//const [files, setFiles] = useState({} as File);
//Nota: files es capturado desde el input

export function onChangeImputFile(
  event: React.ChangeEvent<HTMLInputElement>,
  setFiles: React.Dispatch<React.SetStateAction<File>>
) {
  if (event.target.files && event.target.files.length > 0) {
    setFiles(event.target.files[0]);
    return;
  }
}

//subida de archivos
export async function addFileStorage(
  files: File,
  directoryFolder: string
): Promise<void> {
  try {
    const fileRef = ref(storage, `${directoryFolder}/${files.name}`);
    const snapshot = await uploadBytes(fileRef, files);
    const urlData = await getDownloadURL(snapshot.ref);

    console.log("Archivo disponible en", urlData);
    toast.success(`¡Subiste un blob o archivo!: ${snapshot.ref.fullPath}`);
  } catch (error: any) {
    console.error("Hubo un error al subir el archivo :", error);
  }
}

//eliminar archivo de storage
export async function deleteFileStorage(urlData: string): Promise<void> {
  const fileRef = ref(storage, urlData);
  try {
    await deleteObject(fileRef);

    toast.success(`¡Archivo eliminado con éxito!: ${fileRef.name}`);
  } catch (error) {
    console.error("Hubo un error al eliminar el archivo :", error);
  }
}

//subida de archivos con estado de upload -ok
export async function addFileStorageWithStateProgress2(
  files: File,
  setUrl: React.Dispatch<React.SetStateAction<string>>,
  setProgress: React.Dispatch<React.SetStateAction<number>>
): Promise<void> {
  try {
    const fileRef = ref(storage, files.name);
    const uploadTask = uploadBytesResumable(fileRef, files);

    uploadTask.on(
      "state_changed",
      (snapshot) => {
        // Puedes usar snapshot para mostrar el progreso de la subida
        const progress =
          (snapshot.bytesTransferred / snapshot.totalBytes) * 100;

        setProgress(Math.floor(progress));
      },
      (error: FirebaseError) => {
        console.error(error.message);
        throw error;
      },
      async () => {
        try {
          const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
          console.log("¡Archivo subido con éxito url!: ", downloadURL);
          setProgress(0);

          toast.success("¡Subiste un blob o archivo!");

          setUrl(downloadURL);
        } catch (error) {
          console.error("Hubo un error al obtener la URL de descarga: ", error);
          throw error;
        }
      }
    );
  } catch (error: any) {
    console.error("Hubo un error al subir el archivo :", error);
  }
}

//subida de archivos con estado de upload-revisar
/* export async function addFileStorageWithStateProgress(
  files: File,
  setUrl: React.Dispatch<React.SetStateAction<string>>,
  setProgress: React.Dispatch<React.SetStateAction<number>>
): Promise<void> {
  try {
    const fileRef = ref(storage, files.name);

    return new Promise((resolve, reject) => {
      const uploadTask = uploadBytesResumable(fileRef, files);

      uploadTask.on(
        "state_changed",
        (snapshot) => {
          // Puedes usar snapshot para mostrar el progreso de la subida
          const progress =
            (snapshot.bytesTransferred / snapshot.totalBytes) * 100;

          setProgress(Math.floor(progress));
        },
        (error: FirebaseError) => {
          console.error(error.message);
          reject(error.message);
        },
        () => {
          getDownloadURL(uploadTask.snapshot.ref).then(
            (downloadURL: string) => {
              console.log("¡Archivo subido con éxito url!: ", downloadURL);
              setProgress(0);

              toast.success("¡Subiste un blob o archivo!");

              setUrl(downloadURL);
              resolve();
            }
          );
        }
      );
    });
  } catch (error: any) {
    console.error("Hubo un error al subir el archivo :", error);
  }
} */

CÓDIGO ClIENTE

PageUpload.tsx

"use client";
import { useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import {
  addFileStorage,
  addFileStorageWithStateProgress,
  deleteFileStorage,
} from "@/firebase/addFileStorage";

const PageUpload = () => {
  const [files, setFiles] = useState({} as File);
  const [progress, setProgress] = useState(0);
  const [url, setUrl] = useState("");

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    // addFileStorage(files, "/");
    addFileStorageWithStateProgress(files, setUrl, setProgress);
  };
  return (
    <>
      <Toaster />
      <h1 className="text-center">Subir datos</h1>
      <form onSubmit={handleSubmit}>
        <input
          type="file"
          name="inputFile"
          onChange={(event) => setFiles(event.target.files![0])}
          placeholder="Selecciona una imagen"
        />
        <button type="submit">Upload Image</button>
      </form>
      <div className="pt-4">
        progress: {progress} %
        <progress value={progress} max="100" />
      </div>
      <p className="pt-4">Ruta:{url}</p>
      <button
        className="pt-4"
        onClick={() =>
          deleteFileStorage(
            "https://firebasestorage.googleapis.com/delete%2*_ga*.**asdasdasdasdsddasdasdasdasdasdsadasasdas"
          )
        }
      >
        Eliminar Imagen
      </button>
    </>
  );
};

export default PageUpload;



NOTAS DEL DESARROLLADOR

Un paso a paso:

-Función onChangeInputFile:

Esta función se encarga de manejar los cambios en el input de archivos (<input type="file">). Cuando el usuario selecciona un archivo, actualiza el estado con ese archivo para su posterior carga.

-Función addFileStorage:

Esta función se utiliza para cargar un archivo en Firebase Storage. Recibe dos parámetros:

files (File): El archivo que se va a cargar. directoryFolder (string): La carpeta en Firebase Storage donde se almacenará el archivo.

-Creación de la Referencia al Archivo:

Creamos una referencia al archivo en Firebase Storage utilizando ref. Especificamos la ubicación del archivo dentro de la carpeta directoryFolder con el nombre original del archivo.

-Subida del Archivo:

Utilizamos uploadBytes para cargar el archivo en Firebase Storage. La referencia al archivo y el archivo en sí se pasan como argumentos.

-Obtención de la URL de Descarga:

Luego de que el archivo se ha cargado con éxito, obtenemos la URL de descarga del archivo utilizando getDownloadURL. Esta URL se puede utilizar para acceder al archivo desde cualquier lugar.

-Manejo de Errores con try-catch:

Si ocurre algún error durante el proceso de carga del archivo, se captura en el bloque catch. Luego, registramos el error en la consola para su posterior depuración.

-Referencia a la Colección:

Creamos una referencia al documento específico que deseamos eliminar utilizando la función doc. Tomamos la configuración de Firestore (firestoreDb), el nombre de la colección y el identificador del documento como argumentos.


Regresar al Blog.

© Copyright 2024 ToscaDevJS.