🎾 vue-tennis | SSR Migration(Nuxt + Firebase) | 2. Firebase Usage

protect-meΒ·2021λ…„ 10μ›” 21일
0
post-thumbnail

SSR Migration(Nuxt + Firebase) Series
1. Set Environment
2. Firebase Usage πŸ‘ˆπŸ»



πŸ”₯ firestore usage


REF : https://firebase.nuxtjs.org/guide/usage

  • pages > index.vue λ‚΄μš© μΆ”κ°€
<script>
export default {
  async mounted() {
    console.log('mounted')
    const db = await this.$fire.firestore
    // const users = this.$fire.firestore.collection('users').doc(uid).get()
    console.log('here', db)
  },
}
</script>
  • console

주의 사항
1. this.$firestore (x) β‡’ this.$fire.firestore (o)
*버전에 따라 닀름(ν•„μžμ˜ ν™˜κ²½ => "@nuxtjs/firebase": "^7.6.1")
2. nuxt.config.js > firebase > services β‡’ firestore: true 확인



πŸ‘¨πŸ»β€πŸš’ functions usage

REF : λ‘œμ»¬μ—μ„œ ν•¨μˆ˜ μ‹€ν–‰
https://firebase.google.com/docs/functions/local-emulator
REF : μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œμ νŠΈμ— Firebase μΆ”κ°€
https://firebase.google.com/docs/web/setup
REF : Functions
https://firebase.google.com/docs/functions/manage-functions?hl=ko

1. μ„ ν–‰

$ npm install -g firebase-tools : firebase-tools μ„€μΉ˜
$ firebase login : firebase에 둜그인

2. firebase μ΄ˆκΈ°ν™”

$ firebase init : functions만 μ„ νƒν•œ ν›„ μ„€μΉ˜
(ν”„λ‘œμ νŠΈ 내에 functions 폴더가 μƒμ„±λœ 것을 확인할 수 있음)

3. nuxt.config.js λ‚΄μš© μˆ˜μ •

  firebase: {
    config: {
      ...
    },
    services: {
      ...
      functions: {
        location: 'asia-northeast3', // firebase project 섀정에 따름
        // Cloud Functions μœ„μΉ˜
        // https://firebase.google.com/docs/functions/locations
      },

4. firebase admin SDK μ„€μ •

localμ—μ„œ myFirebaseProjectλ₯Ό λ‹€λ£° 수 있게 됨
그만큼 λ¦¬μŠ€ν¬κ°€ 크기 λ•Œλ¬Έμ— key 관리에 신경써야 함

1. firebase > myProject > ν”„λ‘œμ νŠΈ μ„€μ • > μ„œλΉ„μŠ€ 계정 > firebase admin SDK ꡬ성 μŠ€λ‹ˆνŽ« 확인

2. ν•˜λ‹¨μ˜ μƒˆ λΉ„κ³΅κ°œ ν‚€ 생성을 ν†΅ν•΄μ„œ ν‚€ νŒŒμΌμ„ λ‹€μš΄λ°›μ€ ν›„ myProject > functions 경둜둜 이동

(key 파일λͺ…을 μ•Œλ§žκ²Œ μˆ˜μ •ν•¨ / ν•„μžμ˜ 경우 vue-tennis-key.json)

3. firebase console λ‚΄ firebase admin SDK ꡬ성 μŠ€λ‹ˆνŽ«μ„ λ³΅μ‚¬ν•˜μ—¬

myProject > functions > index.js에 λΆ™μ—¬λ„£μŒ

const functions = require('firebase-functions')
var admin = require('firebase-admin')
var serviceAccount = require('./vue-tennis-key.json')

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'myDatabaseURL',
})

const db = admin.database()
const fdb = admin.firestore()

4. gitignore 등둝 (μ€‘μš”β—οΈβ—οΈ)

  • root > functions > .gitignore
    root > .gitignoreκ³Ό ꡬ뢄됨에 주의 🚨
node_modules
vue-tennis-key.json
.env

5. μƒˆλ‘œμš΄ ν…ŒμŠ€νŠΈ ν•¨μˆ˜(function) μž‘μ„±

: root > functions > index.js λ‚΄μš© μˆ˜μ •

exports.createUser = functions.auth.user().onCreate(async (user) => {
  console.log('firebase funtions : createUser')
  const { uid, email, displayName, photoURL } = user
  const time = new Date()
  const userInfo = {
    email,
    displayName,
    photoURL,
    nickName: displayName,
    sex: '',
    birth: '',
    location: '',
  }
  await fdb.collection('users').doc(uid).set(userInfo) // set user at Firestore
  userInfo.createdAt = time.getTime()
  db.ref('users').child(uid).set(userInfo) // set user at RealTime Database
})

exports.deleteUser = functions.auth.user().onDelete(async (user) => {
  console.log('firebase funtions : deleteUser')
  const { uid } = user
  await db.ref('users').child(uid).remove()
  await fdb.collection('users').doc(uid).delete()
})

6. ν•¨μˆ˜ 배포(deploy function)

: $ firebase deploy --only functions:createUser
: $ firebase deploy --only functions:deleteUser

7. ν…ŒμŠ€νŠΈ ν•¨μˆ˜ μž‘λ™ 확인

: firebase > myProject > Functions > 둜그

  • μœ„μ—μ„œ μž‘μ„±ν•œ functionμ—μ„œ console둜 찍은 λ‚΄μš©μ„ 확인할 수 있음
  • μ—¬κΈ°μ„œ μ˜ˆμ‹œλ‘œ μž‘μ„±ν•œ createUser ν•¨μˆ˜μ˜ 경우,
    authμ—μ„œ userκ°€ μƒˆλ‘œ μƒμ„±λ˜κ±°λ‚˜ μ‚­μ œλ˜λŠ” 경우λ₯Ό 트리거둜 ν•˜κ³  있기 λ•Œλ¬Έμ—,
    μ•„λž˜ auth usage νŒŒνŠΈμ—μ„œ μž‘μ„±ν•œ μ½”λ“œλ₯Ό 기반으둜 μž‘λ™ν•¨.
    λ”°λΌμ„œ auth usage 파트λ₯Ό μž‘μ„±ν•œ 후에 7. ν…ŒμŠ€νŠΈ ν•¨μˆ˜ μž‘λ™ 확인 λ‚΄μš©μ„ 확인 λ°”λžŒ



πŸš’ auth usage

1. nuxt.config.js λ‚΄μš© μˆ˜μ •

: μ•„λž˜μ™€ 같이 μž‘μ„±ν•  경우, Auth Stateκ°€ 변경될 λ•Œλ§ˆλ‹€ onAuthStateChangedAction이 싀행됨.

  firebase: {
    config: {
      ...
    },
    services: {
      ...
      auth: {
        initialize: {
          onAuthStateChangedAction: 'onAuthStateChanged',
        },
        ssr: true,
        disableEmulatorWarnings: false,
      },
    }
  }

2. pages > mypage.vue λ‚΄μš© μˆ˜μ •

<template>
  <v-container>
    <v-card>
      <v-card-text>
        <v-btn @click="login" :loading="isProcessing">login</v-btn>
        <v-btn @click="logout" :loading="isProcessing">logout</v-btn>
      </v-card-text>
    </v-card>
  </v-container>
</template>

<script>
export default {
  data() {
    return {
      isProcessing: false,
    }
  },
  methods: {
    async login() {
      if (this.isProcessing) return
      this.isProcessing = true
      const provider = new this.$fireModule.auth.GoogleAuthProvider()
      try {
        const snapshot = await this.$fire.auth.signInWithPopup(provider)
      } catch (err) {
        alert('둜그인 μ‹€νŒ¨', err)
        console.log(err)
      } finally {
        this.isProcessing = false
      }
    },

    async logout() {
      if (this.isProcessing) return
      this.isProcessing = true
      try {
        await this.$fire.auth.signOut()
        console.log('λ‘œκ·Έμ•„μ›ƒ 성곡')
      } catch (err) {
        alert('λ‘œκ·Έμ•„μ›ƒ μ‹€νŒ¨.', err)
        console.log(err)
      } finally {
        this.isProcessing = false
      }
    },
  },
}
</script>
  • http://localhost:3000/mypage

3. Vuex(store)

store > state.js

export default () => ({
  user: null,
  fireUser: null,
})

store > mutations.js

mutationsμ—μ„œ state.user = payload와 같이 직접 할당을 ν•˜λ©΄ μ—λŸ¬ λ°œμƒ 🚨

import initialState from './state'

export default {
  RESET_STORE: (state) => {
    Object.assign(state, initialState())
  },

  SET_FIRE_USER: (state, fireUser) => {
    const { uid, email, displayName, photoURL } = fireUser
    state.fireUser = { uid, email, displayName, photoURL }
  },
  
  SET_USER: (state, user) => {
    if (user) {
      const {
        email,
        displayName,
        photoURL,
        nickName,
        sex,
        birth,
        location,
      } = user
      state.user = {
        email,
        displayName,
        photoURL,
        nickName,
        sex,
        birth,
        location,
      }
    } else {
      state.user = null
    }
  },
}

store > actions.js

export default {
  async onAuthStateChanged({ commit }, { authUser }) {
    let unsubscribe = null
    if (!authUser) {
      if (unsubscribe) unsubscribe()
      return
    }
    commit('SET_FIRE_USER', authUser)

    const subscribe = (authUser) => {
      const ref = this.$fire.firestore.collection('users').doc(authUser.uid)
      unsubscribe = ref.onSnapshot((doc) => {
        if (doc.exists) commit('SET_USER', doc.data())
      }, console.error)
    }
    subscribe(authUser)
  },
}


πŸ§―πŸ§‘πŸ»β€πŸš’πŸ‘©πŸ»β€πŸš’πŸ•―



REF : nuxt-firebase-demo

profile
protect me from what i want

0개의 λŒ“κΈ€