๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“š Database/Firebase

[Firebase] Cloud Functions๋กœ Algolia์™€ Firestore ์—ฐ๋™ํ•˜๊ธฐ

by Fomagran ๐Ÿ’ป 2021. 4. 21.
728x90
๋ฐ˜์‘ํ˜•

 

 

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค!

 

์˜ค๋Š˜์€ Cloud Functions ์„ ์ด์šฉํ•ด์„œ Firestore ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ Algolia์˜ ์ธ๋ฑ์Šค๋ฅผ ์—ฐ๋™ํ•˜๋Š”๊ฑธ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ํด๋ผ์šฐ๋“œ ํŽ‘์…˜ ๊ธฐ๋ณธ์„ธํŒ…๊ณผ ์•Œ๊ณ ๋ฆฌ์•„ ๊ธฐ๋ณธ์„ธํŒ…์ด ํ•„์š”ํ•˜๋ฏ€๋กœ 

 

ํด๋ผ์šฐ๋“œ ํŽ‘์…˜์„ธํŒ…์€ ์—ฌ๊ธฐ ์—์„œ ์•Œ๊ณ ๋ฆฌ์•„ ๊ธฐ๋ณธ์„ธํŒ…์€ ์—ฌ๊ธฐ ์—์„œ ๋จผ์ € ๋ณด๊ณ  ์™€์ฃผ์„ธ์š”~

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~


Pod

 

๋จผ์ € Algolia์™€ Cloud Function๊ณผ Firestore๋ฅผ ์ฝ”์ฝ”์•„ํŒŸ์— ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.

 

 pod 'AlgoliaSearchClient', '~> 8.0'
  
 pod 'Firebase/Functions'
 
 pod 'Firebase/Firestore'

 

 

ํ„ฐ๋ฏธ๋„์—์„œ functions๋กœ ์ด๋™ํ›„ npm์œผ๋กœ ์•Œ๊ณ ๋ฆฌ์•„๋ฅผ ์„ค์น˜ํ•ด์ค๋‹ˆ๋‹ค.

 

cd functions
npm install algoliasearch

 

Algolia ๋Œ€์‰ฌ๋ณด๋“œ๋กœ ๋“ค์–ด๊ฐ€ ์•ฑ ์ด๋ฆ„๊ณผ APIํ‚ค๋ฅผ ์ €์žฅํ•ด์ค๋‹ˆ๋‹ค.

 

 

Site Search & Discovery powered by AI

Create AI-powered search & discovery across websites & apps.

www.algolia.com

 

ํ„ฐ๋ฏธ๋„์— ์•ฑ์ด๋ฆ„๊ณผ ์–ด๋“œ๋ฏผ APIKEY๋ฅผ ์ ์–ด์ค๋‹ˆ๋‹ค.

firebase functions:config:set algolia.app="์•ฑ์ด๋ฆ„" algolia.key="์–ด๋“œ๋ฏผAPIKEY"

 

์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ๋ ๊ฑฐ์—์š”!

 


Visual Studio

 

๋น„์ฅฌ์–ผ ์ŠคํŠœ๋””์˜ค์—์„œ ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์˜ functions ํŒŒ์ผ๋กœ ๋“ค์–ด๊ฐ€ index.js ํŒŒ์ผ์„ ์—ด์–ด์ฃผ์„ธ์š”!

 

์•„๋ž˜์™€ ๊ฐ™์ด ๊ธฐ๋ณธ ์„ธํŒ…์„ ํ•ด์ค๋‹ˆ๋‹ค.

//ํด๋ผ์šฐ๋“œ ํŽ‘์…˜ ์„ธํŒ…
const functions = require("firebase-functions");

//์–ด๋“œ๋ฏผ ์„ธํŒ…
const admin = require('firebase-admin');

//์•Œ๊ณ ๋ฆฌ์•„ ์„ธํŒ…
const algoliasearch = require('algoliasearch');

//์•Œ๊ณ ๋ฆฌ์•„ ์•ฑ์•„์ด๋””
const APP_ID = functions.config().algolia.app;

//์•Œ๊ณ ๋ฆฌ์•„ ์–ด๋“œ๋ฏผํ‚ค
const ADMIN_KEY = functions.config().algolia.key;

//์•Œ๊ณ ๋ฆฌ์•„ ํด๋ผ์ด์–ธํŠธ ์„ธํŒ…
const client = algoliasearch(APP_ID, ADMIN_KEY);

//์•Œ๊ณ ๋ฆฌ์•„ ์ธ๋ฑ์Šค ์ด๋ฆ„ ์„ธํŒ…
const index = client.initIndex('์ธ๋ฑ์Šค ์ด๋ฆ„');

//์–ด๋“œ๋ฏผ์„ ํŒŒ์ด์–ด์Šคํ† ์–ด๋กœ ์„ธํŒ…
admin.initializeApp(functions.config().firestore);

 

์ƒ์„ฑ๋˜์—ˆ์„๋•Œ

 

(์•„ํŒŒํŠธ ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์–ด์„œ Apart ๋„ํ๋จผํŠธ๋กœ ์ง€์ •ํ–ˆ์ง€๋งŒ ์ปฌ๋ ‰์…˜์ด๋ฆ„/{์ปฌ๋ ‰์…˜์ด๋ฆ„ + Id}๋กœ ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.)

 

exports.onApartsCreated = functions.firestore.document("Apart/{ApartId}").onCreate((snap, context) => {
    const apart = snap.data();
    const objectID = snap.id;
    index.saveObject({ ...apart, objectID });
});

 

์ˆ˜์ •๋˜์—ˆ์„๋•Œ

 

exports.onApartUpdated = functions.firestore.document("Apart/{ApartId}").onUpdate((snap, context) => {

    const apart = snap.after.data();
    const objectID = snap.after.id;
    index.saveObject({ ...apart, objectID });
});

์‚ญ์ œ๋˜์—ˆ์„๋•Œ

 

exports.onApartDeleted = functions.firestore.document("Apart/{ApartId}").onDelete((snap, context) => {

    const id = snap.id;
    index.deleteObject(id);
});

 

ํ•จ์ˆ˜๋ฐฐํฌ

 

์œ„์™€ ๊ฐ™์ด ์ƒ์„ฑ,์ˆ˜์ •,์‚ญ์ œ ๋˜์—ˆ์„๋•Œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์‹œ๊ณ  ํŒŒ์ด์–ด๋ฒ ์ด์Šค์— ํ•จ์ˆ˜๋ฅผ ๋ฐฐํฌํ•ด์ค๋‹ˆ๋‹ค.

 

ํ„ฐ๋ฏธ๋„์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

firebase deploy --only functions

(ํ˜น์‹œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋œจ์‹œ๋Š” ๋ถ„๋“ค์€ .eslintrc.js ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๊ณ  eslint๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”. ์ด๊ฒŒ ๋งž๋Š” ๋ฐฉ๋ฒ•์ธ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์œผ๋‚˜ ์ „ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค....)

 

--eslint init

 

์˜ค๋ฅ˜๊ฐ€ ๋‚˜์‹  ๋ถ„๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ธํŒ…ํ•ด์ฃผ์„ธ์š”.

 

 

์„ฑ๊ณต์ ์œผ๋กœ ํ•จ์ˆ˜๊ฐ€ ๋ฐฐํฌ๋˜์—ˆ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด Deploy complete๊ฐ€ ๋‚˜์˜ค๊ณ  ํ”„๋กœ์ ํŠธ ์ฝ˜์†” ์ฃผ์†Œ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 


Firebase Console

 

ํŒŒ์ด์–ด๋ฒ ์ด์Šค ์ฝ˜์†”๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

 

Cloud Functions ํƒญ์— ๋ณด๋ฉด ์„ฑ๊ณต์ ์œผ๋กœ 3๊ฐœ์˜ ํ•จ์ˆ˜๊ฐ€ ์˜ฌ๋ผ๊ฐ€์žˆ๋Š”๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

 

์œ„ ํ•จ์ˆ˜๋“ค์€ ํŒŒ์ด์–ด์Šคํ† ์–ด์—์„œ ์ƒ์„ฑ,์ˆ˜์ •,์‚ญ์ œ๋˜์—ˆ์„๋•Œ ์•Œ์•„์„œ ์‹คํ–‰๋ ๊ฑฐ์—์š”.

 


Xcode

 

์ด์ œ ํ”„๋กœ์ ํŠธ๋กœ ์ด๋™ํ•ด์„œ ํŒŒ์ด์–ด์Šคํ† ์–ด์— ๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

 

ํŒŒ์ด์–ด์Šคํ† ์–ด๋ฅผ import ํ•ด์ฃผ์‹œ๊ณ 

import FirebaseFirestore

 

์ƒ์„ฑ

 

Firestore์— ๋ฌธ์„œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

    Firestore.firestore().collection("Apart").addDocument(data: ["aptName":"ํ•œ์‚ฌ๋ž‘์•„ํŒŒํŠธ"])

 

Apart ์ปฌ๋ ‰์…˜์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒ๊ธฐ๊ณ 

 

 

 

Functions์˜ ๋กœ๊ทธํƒญ์„ ๊ฐ€์„œ ํ™•์ธํ•ด๋ณด๋ฉด

 

 

Apart๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์„๋•Œ์˜ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

๋˜ํ•œ Algolia์— Indicies๋กœ ๊ฐ€๋ฉด Apart ์ธ๋ฑ์Šค๊ฐ€ ์ƒ๊ธฐ๊ณ  ํ•ด๋‹น ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋œ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์ˆ˜์ •

 

ํŒŒ์ด์–ด์Šคํ† ์–ด์—์„œ ํ•ด๋‹น ๋ฌธ์„œ์˜ ์•„ํŒŒํŠธ ์ด๋ฆ„์„ ์žฅ๋ฏธ์•„ํŒŒํŠธ๋กœ ๋ฐ”๊ฟ”๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 Firestore.firestore().collection("Apart").document("Gsw0Qg39ZZsXuIcgAUGq").updateData(["aptName":"์žฅ๋ฏธ์•„ํŒŒํŠธ"])

 

ํŒŒ์ด์–ด์Šคํ† ์–ด์—์„œ ์•„ํŒŒํŠธ ์ด๋ฆ„์ด ์žฅ๋ฏธ์•„ํŒŒํŠธ๋กœ ์ˆ˜์ •๋˜์—ˆ๊ณ 

 

 

Functions์˜ ๋กœ๊ทธ๋กœ ๋“ค์–ด๊ฐ€์„œ ํ™•์ธํ•ด๋ณด๋ฉด ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋˜ํ•œ Algolia์˜ ํ•ด๋‹น ์˜ค๋ธŒ์ ํŠธ๋„ ์žฅ๋ฏธ์•„ํŒŒํŠธ๋กœ ์ž˜ ๋ฐ”๋€๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

์‚ญ์ œ

 

๋งˆ์ง€๋ง‰์œผ๋กœ ํ•ด๋‹น ๋ฌธ์„œ๋ฅผ ํŒŒ์ด์–ด์Šคํ† ์–ด์—์„œ ์‚ญ์ œํ•ด์ค๋‹ˆ๋‹ค.

 

Firestore.firestore().collection("Apart").document("Gsw0Qg39ZZsXuIcgAUGq").delete()

 

ํŒŒ์ด์–ด์Šคํ† ์–ด์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋˜๊ณ 

 

Functions์˜ ์‚ญ์ œ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

Algolia์—์„œ๋„ ํ•ด๋‹น ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์‚ญ์ œ๋œ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

 


์˜ค๋Š˜์€ ์ด๋ ‡๊ฒŒ ํด๋ผ์šฐ๋“œ ํŽ‘์…˜์œผ๋กœ ํŒŒ์ด์–ด์Šคํ† ์–ด์™€ ์•Œ๊ณ ๋ฆฌ์•„ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐ์‹œํ‚ค๋Š” ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

์˜ˆ์ „๋ถ€ํ„ฐ ํด๋ผ์šฐ๋“œ ํŽ‘์…˜์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ ๊ตฌ์ฒด์ ์œผ๋กœ ์•Œ์•„๋ณด๊ฒŒ ๋ผ์„œ ๊ธฐ๋ถ„์ด ์ข‹๋„ค์š” ใ…Žใ…Ž

 

ํ˜น์‹œ๋ผ๋„ ํ‹€๋ฆฐ์ ์ด ์žˆ๊ฑฐ๋‚˜ ๊ถ๊ธˆํ•˜์‹  ์ ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”!


Reference

 

fireship.io/lessons/algolia-cloud-functions/

 

www.algolia.com/doc/

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€