Open17

nuxt3

ramo798ramo798

まずは動作確認

npx nuxi init nuxt3-firebase-test
cd nuxt3-firebase-test
npm run dev

http://localhost:3000/にアクセス

ramo798ramo798

pagesのみで運用したいので、app.vueの削除
pagespages/index.vueの作成

ramo798ramo798

eslintの設定

package.json
{
  "private": true,
  "scripts": {
    "dev": "nuxi dev",
    "build": "nuxi build",
    "start": "node .output/server/index.mjs"
  },
  "devDependencies": {
    "@nuxtjs/eslint-config": "^7.0.0",
    "@nuxtjs/eslint-module": "^3.0.2",
    "@typescript-eslint/eslint-plugin": "^5.7.0",
    "@typescript-eslint/parser": "^5.7.0",
    "eslint": "^8.4.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-nuxt": "^3.0.0",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-vue": "^8.2.0",
    "nuxt3": "latest",
    "prettier": "^2.5.1",
    "typescript": "^4.5.4",
    "typescript-eslint": "^0.0.1-alpha.0"
  }
}
.eslintrc.js
module.exports = {
    env: {
        browser: true,
        es2021: true,
    },
    extends: [
        'plugin:vue/vue3-recommended',
        'prettier',
        'plugin:@typescript-eslint/recommended',
        'plugin:nuxt/recommended',
    ],
    parserOptions: {
        ecmaVersion: 13,
        parser: '@typescript-eslint/parser',
        sourceType: 'module',
    },
    plugins: ['vue', '@typescript-eslint', '@typescript-eslint/eslint-plugin'],
    rules: {
        'no-unused-vars': 'off',
    },
};

インストール

npm i

参考
https://www.reddit.com/r/Nuxt/comments/qo28bf/nuxt_3_with_eslint_prettier/

ramo798ramo798

TypeScript の Strict type checks を有効にする

nuxt.config.ts
import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  typescript: {
    strict: true
  }
})
ramo798ramo798

API Routesの動作確認
/server/apiの作成

hello.ts
export interface Hello {
    msg: string;
}

export default () => {
    return {
        msg: 'Hello World',
    };
};
pages/index.vue
<script setup lang="ts">
const { data: test } = useFetch('/api/hello');
</script>

<template>
    <div>
        <p>{{ test }}</p>
    </div>
</template>
{ "msg": "Hello World" }
ramo798ramo798

環境変数の設定

.env
API_KEY=
AUTH_DOMAIN=
PROJECT_ID=
STORAGE_BUCKET=
MESSAGING_SENDER_ID=
APP_ID=
MEASUREMENT_ID=

firebaseの初期化処理

plugins/firebase.ts
import { initializeApp } from 'firebase/app';

const firebaseConfig = {
    apiKey: process.env.API_KEY,
    authDomain: process.env.AUTH_DOMAIN,
    projectId: process.env.PROJECT_ID,
    storageBucket: process.env.STORAGE_BUCKET,
    messagingSenderId: process.env.MESSAGING_SENDER_ID,
    appId: process.env.APP_ID,
    measurementId: process.env.MEASUREMENT_ID,
};

const firebase = initializeApp(firebaseConfig);

export default firebase;
ramo798ramo798

/api/のファイル名は小文字じゃないとuseFeachできないので注意
コレクションtasksはコンソール上でよしなに作ってください

server/api/gettest.ts
import { getFirestore, collection, query, getDocs } from 'firebase/firestore';
import firebase from '../../plugins/firebase';

export interface Tasks {
    id: string;
    name: string;
}

export default async () => {
    const db = getFirestore(firebase);
    const q = query(collection(db, 'tasks'));
    const querySnapshot = await getDocs(q);

    // let tasks: Tasks[];
    const tasks: Tasks[] = [];

    querySnapshot.forEach((doc) => {
        console.log(doc.data());
        const task: Tasks = {
            id: doc.data().id,
            name: doc.data().name,
        };
        tasks.push(task);
    });

    return tasks;
};
index.vue
<script setup lang="ts">
const { data: tasks } = await useFetch('/api/gettest');
</script>

<template>
    <div>
        <p>test</p>
        <div v-for="task in data" :key="task.id">
            <p>{{ task.id }}</p>
            <p>{{ task.name }}</p>
        </div>
    </div>
</template>
ramo798ramo798

macでcloneしてnpm install , npm run devすると

 ERROR  nuxi requires @nuxt/kit to be installed in your project. Try installing nuxt3 or @nuxt/bridge first.                                                                                      13:24:39

  at loadKit (/Users/ramo/.nodebrew/node/v16.13.1/lib/node_modules/nuxt3/node_modules/nuxi/dist/chunks/kit.mjs:140:13)
  at Object.invoke (/Users/ramo/.nodebrew/node/v16.13.1/lib/node_modules/nuxt3/node_modules/nuxi/dist/chunks/dev.mjs:6702:43)
  at processTicksAndRejections (node:internal/process/task_queues:96:5)
  at async _main (/Users/ramo/.nodebrew/node/v16.13.1/lib/node_modules/nuxt3/node_modules/nuxi/dist/chunks/index.mjs:382:7)

になったので対処した。
npm install @nuxt/bridgeのおかげだと思う

ramo798ramo798

そもそもserver/apiにデータ取得処理を書くのがベストなのかが不明
外部からアクセスされる可能性があるが、特に問題ないのか?

ramo798ramo798

pagesにファイルを追加するとrun devし直さないとだめ

ramo798ramo798

ERROR Cannot start nuxt: EPERM: operation not permitted, mkdir 'C:\Users\tako\nuxt3-firebase-test.nuxt'

出る問題

ramo798ramo798

SSR対応
デフォルトではSSRではなくSPAになっているので、nuxt.config.tsでSSRオプションをtrueにします。

nuxt.config.ts
import { defineNuxtConfig } from "nuxt3";

export default defineNuxtConfig({
rootDir: "./project",
ssr: true,
});

ramo798ramo798
useFireAuth.ts
import { getAuth, signInWithPopup, TwitterAuthProvider } from 'firebase/auth';
import { firebaseInit } from './firebaseInit';

export const useFireAuth = () => {
    const auth = getAuth(firebaseInit());

    const testAuth = async () => {
        const provider = new TwitterAuthProvider();
        await signInWithPopup(auth, provider)
            .then((result) => {
                const user = result.user;
                console.log(user);
            })
            .catch((error) => {
                const errorCode = error.code;
                const errorMessage = error.message;
                const email = error.email;
                const credential =
                    TwitterAuthProvider.credentialFromError(error);
                console.log(4, errorCode);
                console.log(5, errorMessage);
                console.log(6, email);
                console.log(7, credential);
            });
    };

    return {
        testAuth,
    };
};
 [worker] Component auth has not been registered yet

がでるけどログイン処理はできる

ramo798ramo798

<script setup lang="ts">
<script lang="ts">
の併用のときは
const f1 = useFirestore();を2回やらないといけない