Sausage Erectos X Firebase Auth × プリランチゲート
Firebase Auth×プリランチゲート──Coming Soon画面の裏側
Sausage Erectosのローンチ前、サイトにアクセスした一般ユーザーには「Coming Soon」画面を表示し、管理者だけが実際のサイトを閲覧できるプリランチゲートを実装した。Firebase Authenticationを使ったこの仕組みの全容を解説する。
Firebase Authの初期設定
Firebase Consoleでプロジェクトを作成し、Authenticationを有効化する。
// firebase.js
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
};
export const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
環境変数は.envファイルで管理。Viteのプレフィックス規則により、VITE_で始まる変数のみがクライアントサイドに公開される。
Google / Appleログインの実装
ソーシャルログインの実装はFirebaseが大幅に簡略化してくれる。
import { GoogleAuthProvider, OAuthProvider, signInWithPopup } from 'firebase/auth';
// Google ログイン
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
try {
const result = await signInWithPopup(auth, provider);
return result.user;
} catch (error) {
console.error('Google sign-in failed:', error);
}
}
// Apple ログイン
async function signInWithApple() {
const provider = new OAuthProvider('apple.com');
provider.addScope('email');
provider.addScope('name');
try {
const result = await signInWithPopup(auth, provider);
return result.user;
} catch (error) {
console.error('Apple sign-in failed:', error);
}
}
Apple Sign-Inの場合、Apple Developer Programへの登録とService IDの設定が必要で、Firebase Console側でもAppleプロバイダの設定が必要になる。この設定が最も時間がかかった。
管理者判定ロジック
ログイン後、そのユーザーが管理者かどうかを判定する。方法は、サーバーサイドの管理者APIにリクエストを送ること。
async function checkAdmin(user) {
const token = await user.getIdToken();
const res = await fetch('/api/admin/stats', {
headers: { Authorization: `Bearer ${token}` },
});
if (res.ok) {
// 管理者APIにアクセスできた = 管理者
sessionStorage.setItem('isAdmin', 'true');
return true;
}
return false;
}
サーバーサイドでは、Firebase Admin SDKでトークンを検証し、UIDがホワイトリストに含まれているかをチェックする。
sessionStorageによるバイパス
開発中、毎回ログインするのは面倒だ。sessionStorageにフラグを立てることで、プリランチゲートをバイパスできるようにした。
// 開発者コンソールで実行
sessionStorage.setItem('bypassGate', 'true');
location.reload();
このバイパスは本番環境ではVITE_PRELAUNCH環境変数と組み合わせて制御する。
const isPrelaunch = import.meta.env.VITE_PRELAUNCH === 'true';
const isBypassed = sessionStorage.getItem('bypassGate') === 'true';
const isAdmin = sessionStorage.getItem('isAdmin') === 'true';
if (isPrelaunch && !isBypassed && !isAdmin) {
showComingSoon();
}
Coming Soon画面のデザイン
プリランチ画面は、単なるブロッカーではなく、ブランドの第一印象を決めるものだ。CSSアニメーションを使って印象的な画面を作った。
.coming-soon {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #0a0a0a;
color: #ffffff;
}
.coming-soon h1 {
font-size: 4rem;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.coming-soon .countdown {
font-variant-numeric: tabular-nums;
letter-spacing: 0.1em;
}
カウントダウンタイマー、メール登録フォーム(ローンチ通知用)、SNSリンクを配置。ミニマルだが、ブランドのトーンが伝わるデザインを心がけた。
VITE_PRELAUNCH環境変数の制御
ローンチ当日、やることはたった一つ。環境変数を変更してデプロイするだけだ。
# .env.production
VITE_PRELAUNCH=false # これを true → false に変えるだけ
このシンプルさが重要だ。ローンチ当日は何が起こるかわからない。複雑な手順は事故のもとだ。環境変数を1つ変えるだけでローンチできるようにしておくことで、精神的な余裕が生まれる。
プリランチゲートは「見せない」ための技術だが、その目的は「見せたとき」のインパクトを最大化することだ。期待を膨らませる待ち時間もまた、プロダクト体験の一部である。