๐Ÿ‘ฉ‍๐Ÿ’ป/Firebase

[firebase] Vue.js + Element UI + Firebase : firestore์—์„œ sub-collection๋กœ ๋ฐ์ดํ„ฐ ๊ณ„์ธตํ™”ํ•˜๊ธฐ

ํ•œ๋‚˜ 2020. 12. 31. 21:45

 

firebase.firestore()
	.collection("firstCollection").doc("firstDoc")
    .collection("secondCollection").add(dataToAdd);
// firebase.js

// ..
export const dbService = firebase.firestore();
export const bookRecordRef = dbService.collection("bookRecord");

์ด์ „ ํฌ์ŠคํŠธ์—์„œ Vue.js ํ”„๋กœ์ ํŠธ์—์„œ firebase๋ฅผ ์—ฐ๊ฒฐํ•ด ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค๋ค˜๋Š”๋ฐ, ์˜ค๋Š˜์€ ๊ฑฐ๊ธฐ์— ์ด์–ด ๊ณ„์ธต์  ๊ตฌ์กฐํ™”๋ฅผ ์กฐ๊ธˆ ๋” ๋‹ค๋ค„๋ณด๋ ค๊ณ  ํ•œ๋‹ค. ๊ฐ„๋‹จํ•œ book tracker web app์„ ๋งŒ๋“œ๋Š” ์ค‘์ธ๋ฐ, ์•„๋ž˜ ์ด๋ฏธ์ง€์ฒ˜๋Ÿผ bookRecord๋ผ๋Š” ์ปฌ๋ ‰์…˜ ๋‚ด์— ์œ ์ €์˜ ๊ณ ์œ ํ•œ uid๋ฅผ ์ด๋ฆ„์œผ๋กœ ํ•˜๋Š” doc(์ปฌ๋ ‰์…˜์˜ ํ•˜์œ„ ๋‹จ์œ„)์ด ์žˆ๊ณ , ๊ทธ ์•ˆ์— bookInfo๋ผ๋Š” collection์„ ๊ฐ–๋„๋ก ํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค. app์ด ์ปค์ง€๋ฉด ์ •๋ฆฌํ•˜๊ธฐ๊ฐ€ ํž˜๋“ค ๊ฒƒ ๊ฐ™์•„ ์ด๋ ‡๊ฒŒ ๋ฏธ๋ฆฌ ๋‚˜๋ˆ„์–ด๋ดค๋Š”๋ฐ, ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ œ๋Œ€๋กœ ์ฝ์ง€ ์•Š๊ณ  collection ์•„๋ž˜์— ๋˜ ๋‹ค๋ฅธ collection์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•˜๋‹ˆ๊นŒ ๋‹น์—ฐํžˆ ์•ˆ ๋๋‹ค (..^^)

 

bookRecord(collection) > user์˜ UID๋ฅผ ์ด๋ฆ„์œผ๋กœ ํ•˜๋Š” doc > ๊ทธ ํ•˜์œ„์˜ bookInfo๋ผ๋Š” sub-collection
ํ•ด๋‹น ์ปฌ๋ ‰์…˜์—๋Š” ์œ ์ €๊ฐ€ ์ง์ ‘ ๋“ฑ๋กํ•œ book review ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ๋‹ค. ์ด๋ฆ„์€ ์ž๋™์ƒ์„ฑ๋˜๋„๋ก ํ–ˆ๋‹ค.

 

๊ณต์‹ ๋ฌธ์„œ๋Š” firestore>data-model ํ•ญ๋ชฉ์— ์ž˜ ๋‚˜์™€์žˆ๋‹ค. ์•„๊นŒ ์ปฌ๋ ‰์…˜ ์•ˆ์— ์ปฌ๋ ‰์…˜์„ ๋„ฃ์œผ๋ ค๊ณ  ์‹œ๋„ํ–ˆ๋˜ ๊ฒƒ์€ ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ "์ปฌ๋ ‰์…˜์€ ์˜ค๋กœ์ง€ ๋ฌธ์„œ(doc)๋งŒ ํฌํ•จํ•œ๋‹ค"๊ณ  ์ž˜ ์„ค๋ช…๋˜์–ด ์žˆ์–ด์„œ, ์™œ ํ‹€๋ ธ๋Š”์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋˜ํ•œ, ๊ฐ’์ด ์žˆ๋Š” ์›์‹œ ํ•„๋“œ๋ฅผ ํฌํ•จํ•˜๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ์ปฌ๋ ‰์…˜์„ ํฌํ•จํ•  ์ˆ˜ ์—†๋‹ค.

 

 

 

๋ฌธ์„œ์˜ ์˜ˆ์ œ๋ฅผ ๋”ฐ๋ผ์„œ, ๋‚˜๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

 

import { bookRecordRef } from "@/firebase";
import { parseTime } from "@/utils/index";

export default {
	props: ["userUID"],
    data() {
    	return {
        	cardForm: {
            	title: "",
        		writer: "",
        		genre: "",
        		quote: "",
        		review: "",
        		created: ""
            }
        }
    },
    //...
    methods: {
    	async onSubmit() {
      	try {
        	this.cardForm.created = parseTime(new Date(Date.now()));
        	await bookRecordRef
          	.doc(`${this.userUID}`)
          	.collection("bookInfo")
          	.add(this.cardForm);
      	} catch (err) {
        	// ์—๋Ÿฌ ์ฒ˜๋ฆฌ
      	}
    },
    }
}

์ด๋•Œ, bookRecordRef๋Š” firebase๋กœ๋ถ€ํ„ฐ ๋ฐ”๋กœ importํ•ด์ฃผ๋Š”๋ฐ, ์ฝ”๋“œ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ firebase.js์— ๋ฏธ๋ฆฌ collection์„ ๋“ฑ๋กํ•ด๋‘์—ˆ๋‹ค.

 

// firebase.js

export const dbService = firebase.firestore();
export const bookRecordRef = dbService.collection("bookRecord");

 

ํ’€์–ด์“ฐ๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.


firebase.firestore().collection("firstCollection").doc("firstDoc")
					.collection("secondCollection").add(dataToAdd);

๊ฐ„๋‹จํ•œ ์ž…๋ ฅ ํผ์— ์ ๋‹นํ•œ ๋ฉ”์„ธ์ง€๋ฅผ ์ ์–ด์ฃผ๊ณ , submit์„ ๋ˆ„๋ฅด๋ฉด,
๋ฐ์ดํ„ฐ๋„ ์ž˜ ๊ฐ€์ง€๊ณ  ์˜ค๋„๋ก ํ–ˆ๋‹ค.

 

์ปฌ๋ ‰์…˜์˜ ์ƒํƒœ.

 

๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ฌ ๋•Œ๋Š”,์•„๊นŒ์™€ ๋น„์Šทํ•œ ๋ฌธ๋ฒ•์„ ์“ด๋‹ค. ๊ฐ€์ง€๊ณ  ์˜ค๊ณ ์ž ํ•˜๋Š” collection ์งธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋“ค๊ณ  ์˜ฌ ๋•Œ ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค. bookRecord๋ฅผ ๋Œ๋ฉฐ ๋ฏธ๋ฆฌ data()์— ์„ ์–ธํ•ด๋‘” ๋นˆ ๊ฐ์ฒด์ธ bookList์— pushํ•ด์ค€๋‹ค.

async getBookRecord(userUID) {
      const bookRecord = await bookRecordRef
        .doc(`${userUID}`)
        .collection("bookInfo")
        .get();
      bookRecord.forEach(doc => {
        const records = { ...doc.data() };
        this.bookList.push(records);
      });
    },