Supabase Storage に日本語を使うと Invalid Key エラー
に公開背景
ファイルのアップロード先として Supabase Storage を使用しています。
ユーザーが選択した日本語ファイル名をそのまま使用してアップロードを試みました。しかし、以下のエラーが発生しました。
{
"error": "Invalid Key",
"message": "Invalid key: <例: 日本語ファイル名>"
}
解決方法
日本語ファイル名や特殊文字を含むファイル名をアップロードするには、Base64 エンコード/デコードを利用します。
ただし、btoa/atob はマルチバイト文字列に対応していません。そのため、文字列を一度シングルバイト(UTF-8 エンコード)に変換してから Base64 に変換する必要があります。
詳細については Base64 - Unicode 問題 | MDN を参照してください。
// https://github.com/supabase/storage/issues/133#issuecomment-2459780097 を参考
function base64ToBytes(base64: string) {
const binString = atob(base64);
return Uint8Array.from(binString, (m) => m.codePointAt(0)!);
}
function decodeBase64(base64: string) {
try {
return new TextDecoder().decode(base64ToBytes(encoded));
} catch {
return encoded;
}
}
function bytesToBase64(bytes: Uint8Array) {
const binString = Array.from(bytes, (byte) =>
String.fromCodePoint(byte),
).join("");
return btoa(binString);
}
function encodeToBase64(str: string) {
return bytesToBase64(new TextEncoder().encode(str));
}
// ファイルをアップロードするとき
client.storage.from("file").upload(`${encodeToBase64(attachment.name)}`, attachment);
// ファイルを表示するとき
const result = await client.storage.from(“file").list();
const fileNames = result.data?.map(file => decodeBase64(file.name));
備考
この問題は日本語ファイル名に限らず、Amazon S3 の「Characters to avoid」に含まれる文字を使用した場合にも発生します。
Supabase Storage の内部実装は Amazon S3 を基盤としていますが、Supabase ライブラリではより厳格なチェックを行っており、エラーが発生する仕様です。