Editor-Jsでfirebase storageに画像をアップロード(ざっくり)

10/15/2023

このブログ記事の執筆にはEditorJsを使用しています

EditorJsはちょこっとでも触ったことがある前提で

  image: {
          class: ImageTool,
          config: {
            types: '.jpg, .jpeg, .png',
            captionPlaceholder: '画像のaltを入力',
            //ここにupLoader
            uploader: {
              async uploadByFile(file: File) {
                const url = await uploadImage(file);
                return { success: 1, file: { url: url } };<-これで表示してくれるようになる
              },
            },
          },
        },

ここからuploadImageを作っていきます

firebaseのプロジェクト概要ページで「アプリを追加」をクリック

Image

この後の手順はいろいろなところに書かれているので割愛します

今回firebase storageの権限は読み書き制限なしとしておきます

allow read, write

諸々の設定が終わった後lib/frebase.tsの中身はこんな感じです

import { initializeApp } from 'firebase/app';
import { getStorage } from 'firebase/storage';
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_APIKEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_STORAGE_BUCKET,
  messagingSenderId:
    process.env.NEXT_PUBLIC_FIREBASE_STORAGE_MESSAGINGSENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_APP_ID,
  measurementId: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_MEASUREMENT_ID,
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const storage = getStorage(app); <-これをexportしておく

lib/uploadImage.tsを作ります

then/catchでやる場合

import { storage } from './firebase';<-これがfirebase.tsでexportしたやつ
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
export const uploadImage = async (file: File, postId: string) => {
   let uploadResult = '';
  const path = `images/${postId}/${file.name}`;
  const storageRef = ref(storage, path);
   await uploadBytes(storageRef, file)
     .then(async (snapshot) => {
       console.log('アップロードに成功しました', snapshot);
       await getDownloadURL(storageRef).then(function (url) {
         uploadResult = url;
       });
     })
     .catch((error) => {
       console.log('アップロードに失敗しました');
     });
   return uploadResult;
};

try/catchでやる場合

import { storage } from './firebase';
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
export const uploadImage = async (file: File, postId: string) => {
  const path = `images/${postId}/${file.name}`;
  const storageRef = ref(storage, path);
  try {
    await uploadBytes(storageRef, file);
    const url = await getDownloadURL(storageRef);
    return url;
  } catch (error) {
    console.log('アップロードに失敗しました', error);
    return '';
  }
};

${postId}はfirebase Storage内のフォルダを動的に変えたい場合に使用します
例えば記事ごとに分けたいなどに対応するときに使います

自分の場合は記事ごとに分けたい、しかし新規登録の時はidも何もないので初回にid的なものを作成する入力欄を作り

Image

この文字列のフォルダを指定するようにしています(images/${postId}/${file.name})

この入力欄に入力された文字はhasura cloudの記事テーブルに一緒に保存され、再編集の際にも同じフォルダを指定できるようにしています

react-hook-formを使用しているため任意のタイミングで入力欄の値を取得できるので

const uploader = async (file: File) => {
    //インプットの値をgetValueで取得
    const postId = getValues('postId');
    const response = await uploadImage(file, postId);
    return response;
  };

このようなuploadImageをラップする関数を作り、このラップした関数をImageToolのuploaderに渡しています

以上!