如何使用 ReactJS 将文件上传到 Firebase 存储

Firebase 存储提供了一种简单的方法来存储用户生成的数据,例如图像、视频和音频文件。 它与 Firebase 身份验证集成,因此您可以控制谁有权访问文件。

如何使用 ReactJS 将文件上传到 Firebase 存储
Firebase 存储可让您上传任何类型的用户数据。

Firebase 存储提供了一种简单的方法来存储用户生成的数据,例如图像、视频和音频文件。 它与 Firebase 身份验证集成,因此您可以控制谁有权访问文件。

您可以使用 Firebase 存储大量内容,因为它会自动扩展以满足您的需求。 与 React 等第三方框架一起使用很简单。

项目设置

要将文件上传到 Firebase 存储,您需要创建一个 Web 表单,允许用户从文件系统中选择一个文件。首先使用 create-react-app 创建一个 React 应用程序。 运行此命令以生成名为 firebase-upload 的 React 项目:

npx create-react-app firebase-upload

为简单起见,您只需要一个接受文件的输入按钮和一个上传按钮。 用以下代码替换 App.js 的内容。

import { useState } from "react"
 
function App() {
    const [file, setFile] = useState("");
 
    // Handles input change event and updates state
    function handleChange(event) {
        setFile(event.target.files[0]);
    }
 
    return (
        <div>
            <input type="file" accept="image/*" onChange={handleChange}/>
            <button>Upload to Firebase</button>
        </div>
    );
}
 
export default App;

在上面的代码中,input 标签的 accept 属性被设置为只允许图像。 handleChange() 函数处理输入更改并更新状态以存储选取的文件。

设置 Firebase

在将文件上传到 Firebase 存储之前,您需要创建一个 Firebase 项目。

创建一个 Firebase 项目

按照以下说明创建 Firebase 项目:

  • 转到 Firebase 控制台页面并单击添加项目或创建项目(如果您是第一次创建项目)。
  • 为您的项目命名,然后单击继续。
  • 取消选择 Google Analytics,因为此项目不需要它,然后单击创建项目。
  • 项目准备就绪后,单击继续。
  • 单击项目概览页面上的 Web 图标以注册 Web 应用程序。
  • 为您的应用程序起一个昵称,然后单击“注册”。
  • 复制提供的配置对象。 您将需要它来将您的应用程序连接到 Firebase。

创建云存储桶

Firebase 将文件存储在云存储桶中。 请按照以下步骤创建它:

  • 在项目概览页面上,单击左侧导航面板上的存储选项卡。
  • 单击开始并选择测试模式。
  • 选择默认存储桶位置并单击完成。

您现在已准备好开始将文件上传到 Firebase 存储。

将 Firebase 添加到 React

在您的终端中,导航到您的 React 项目文件夹。 运行以下命令来安装 Firebase SDK:

npm install firebase

创建一个新文件 firebaseConfig.js,并初始化 Firebase。

import { initializeApp } from "firebase/app";
import { getStorage } from "firebase/storage";
 
// Initialize Firebase
const app = initializeApp ({
    apiKey: <apiKey>,
    authDomain: <authDomain>,
    projectId: <projectId>,
    storageBucket: <storageBucket>,
    messagingSenderId: <messagingSenderId>,
    appId: <appId>,
    measurementId: <measurementId>,
});
 
// Firebase storage reference
const storage = getStorage(app);

export default storage;

使用您在创建 Firebase 项目后获得的配置对象来初始化 Firebase 应用程序。最后一行导出 Firebase 存储引用,以便您可以从应用程序的其余部分访问该实例。

创建处理函数以将图像上传到 Firebase

单击上传按钮应触发负责将文件上传到 Firebase 存储的功能。 让我们创建那个函数。

在 App.js 中,添加函数 handleUpload。 在函数中,检查文件是否为非空文件,因为用户可能会在选择文件之前单击上传按钮。 如果文件不存在,则发出警报,告知用户先上传文件。

function handleUpload() {
    if (!file) {
        alert("Please choose a file first!")
    }
}

如果该文件存在,则创建一个存储引用。 存储引用充当指向您要操作的云中文件的指针。首先导入您在 firebaseConfig.js 文件中创建的存储服务。

import storage from "./firebaseConfig.js"

从 Firebase 存储实例导入 ref 并将存储服务和文件路径作为参数传递。

import {ref} from "firebase/storage"
 
function handleUpload() {
    if (!file) {
        alert("Please choose a file first!")
    }
 
    const storageRef = ref(storage, `/files/${file.name}`)
}

接下来,通过将 Firebase 存储实例传递给 uploadBytesResumable() 函数来创建上传任务。 您可以使用多种方法,但这个特定的方法允许您暂停和恢复上传。 它还公开进度更新。

uploadBytesResumable() 函数接受存储引用和要上传的文件。

import {
    ref,
    uploadBytesResumable 
} from "firebase/storage";
 
function handleUpload() {
    if (!file) {
        alert("Please choose a file first!")
    }
 
    const storageRef = ref(storage, `/files/${file.name}`)
    const uploadTask = uploadBytesResumable(storageRef, file);
}

在文件上传时监视进度和处理错误,监听状态变化、错误和完成。

import {
    ref,
    uploadBytesResumable,
    getDownloadURL 
} from "firebase/storage";
 
function handleUpload() {
    if (!file) {
        alert("Please choose a file first!")
    }
 
    const storageRef = ref(storage,`/files/${file.name}`)
    const uploadTask = uploadBytesResumable(storageRef, file);
 
    uploadTask.on(
        "state_changed",
        (snapshot) => {
            const percent = Math.round(
                (snapshot.bytesTransferred / snapshot.totalBytes) * 100
            );
 
            // update progress
            setPercent(percent);
        },
        (err) => console.log(err),
        () => {
            // download url
            getDownloadURL(uploadTask.snapshot.ref).then((url) => {
                console.log(url);
            });
        }
    ); 
}

这里,state_changed事件有3个回调函数。 在第一个函数中,您要跟踪上传进度和上传进度状态。 在第二个回调函数中,处理上传不成功的错误。最后一个函数在上传完成后运行,获取下载 URL,然后将其显示在控制台上。 在实际应用程序中,您可以将其保存在数据库中。

您可以使用百分比状态显示上传的进度状态。 同时在上传按钮上添加一个onClick事件来触发handleUpload函数。

import { useState } from "react";
 
function App() {
    const [percent, setPercent] = useState(0);
 
    return (
        <div>
            <input type="file" onChange={handleChange} accept="" />
            <button onClick={handleUpload}>Upload to Firebase</button>
            <p>{percent} "% done"</p>
        </div>
    )
}

下面是 App.js 的完整代码:

import { useState } from "react";
import { storage } from "./firebaseConfig";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
 
function App() {
    // State to store uploaded file
    const [file, setFile] = useState("");
 
    // progress
    const [percent, setPercent] = useState(0);
 
    // Handle file upload event and update state
    function handleChange(event) {
        setFile(event.target.files[0]);
    }
 
    const handleUpload = () => {
        if (!file) {
            alert("Please upload an image first!");
        }
 
        const storageRef = ref(storage, `/files/${file.name}`);
 
        // progress can be paused and resumed. It also exposes progress updates.
        // Receives the storage reference and the file to upload.
        const uploadTask = uploadBytesResumable(storageRef, file);
 
        uploadTask.on(
            "state_changed",
            (snapshot) => {
                const percent = Math.round(
                    (snapshot.bytesTransferred / snapshot.totalBytes) * 100
                );
 
                // update progress
                setPercent(percent);
            },
            (err) => console.log(err),
            () => {
                // download url
                getDownloadURL(uploadTask.snapshot.ref).then((url) => {
                    console.log(url);
                });
            }
        );
    };
 
    return (
        <div>
            <input type="file" onChange={handleChange} accept="/image/*" />
            <button onClick={handleUpload}>Upload to Firebase</button>
            <p>{percent} "% done"</p>
        </div>
    );
}
 
export default App;

使用 Firebase 存储做更多事情

上传文件是 Firebase 存储最基本的功能之一。 但是,Firebase 存储还允许您执行其他操作。 您可以访问、显示、组织和删除文件。

在更复杂的应用程序中,您可能希望对用户进行身份验证以授予他们仅与其文件进行交互的权限。