ファイルシステムに近い感覚でデータを管理する仕組みになっている。
説明 | |
---|---|
コレクション | フォルダのような概念 |
ドキュメント | ファイルのような概念 |
データ | ファイルの中身 |
Reference | ドキュメントやコレクションへのパス情報だけで、中身を持っていない。 データの追加、更新、削除はReferenceに対して行う |
User(users) | 型 |
---|---|
name | 文字列 |
Website(websites) | 型 |
---|---|
title | 文字列 |
Article(articles) | 型 |
---|---|
tilet | 文字列 |
website_id | Reference型 |
/lib/*
などにまとめて置く案もある。/pages/api
を使用するのも良いかもしれない。(ex) アカウントの削除, 重たい処理 etc)また、APIルートを使用すると、FireStoreサーバ <-> Vercel API(AWS)間の距離も気になるところ。
models
やapiルート
,auth
など複数に渡って、呼び出すのでFirebaseの設定だけ切り出しておきます。
lib/firebase.jsimport Firebase from 'firebase/app' import 'firebase/auth' // importしておく import 'firebase/firestore' // importしておく const config = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID, appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, } if (!Firebase.apps.length) { Firebase.initializeApp(config) } export const firebase = Firebase export const auth = firebase.auth() export const db = firebase.firestore()
const db = firebase.firestore() const userRef = await db.collection('users').doc('xxxxxxxxxxx') const userDoc = await userRef.get() if (!userDoc.exists) { console.log('No such document!') } else { const userData = userDoc.data() console.log('Document data:', userDoc.data()) }
作成したモデルクラスarticle.js
で呼び出します。名前空間の関係でクラス名はArticleModel
となっています。
models/article.jsstatic async get(limit = 20) { const articlesRef = await db.collection('articles').limit(limit).get() const articles = await Promise.all(articlesRef.docs.map(async (articleRef) => { // NOTE: Reference型 をそのままページに返すと 「serialized as JSON」 エラーになる // NOTE: Reference型 は Object型 で返ってくる // console.log('typeof: ', typeof a.website_id) const article = articleRef.data() console.log('article: ', article) // Reference型なので、取得するには get() すれば良い const websiteRef = await article.website_id.get() const website = websiteRef.data() console.log('website: ', website) // TODO: Classで返すか検討する return { description: article.description, image_url: article.image_url, title: article.title, url: article.url, website: website } })) return articles }
map()
をPromise.all()
で囲む。(How to use async functions with Array.map in Javascript)get()
で取得する。pages/idnex.jsimport ArticleModel from 'models/article.js' export async function getServerSideProps() { const articles = await ArticleModel.get(20) return { props: { articles: articles } } }
const { uid, displayName, email, photoURL } = req.body const userRef = db.collection('users').doc(uid) const doc = await userRef.get() if (doc.exists) { const userData = doc.data() res.status(200).json(JSON.stringify(userData)) } else { await db.collection('users').doc(uid).set({ name: displayName }, { merge: true }) const docRef = await db.collection('users').doc(uid) const doc = await docRef.get() const userData = doc.data() res.status(200).json(JSON.stringify(userData)) }
How to update the document ID in firebase firestore? [duplicate]
Firebase Authenticationでは、ユーザーを一意に管理できるらしい。このデータとFireStoreのUserを一意にできると解決する。
Firebase Authenticationのデータ
データ | 説明 |
---|---|
ID | |
プロバイダ | |
作成日 | |
ログイン日 | |
ユーザーID |
Firebase AuthenticationのユーザーIDをusers
コレクションのドキュメントIDとして使用する。
Google認証から取得できるデータは以下の通り
データ | 説明 |
---|---|
displayName | Googleアカウントの名前 |
Googleアカウントのメールアドレス | |
photoURL | Googleアカウントのアバター |