Focus On Develop ๐ŸคŸ๐ŸคŸ

[Swift] Cloud Firestore(2) ์‹ค์Šตํ•ด๋ณด๊ธฐ ๋ณธ๋ฌธ

iOS [Swift]/๊ธฐ์ดˆ๋ฅผ ํƒ„ํƒ„ํžˆ!

[Swift] Cloud Firestore(2) ์‹ค์Šตํ•ด๋ณด๊ธฐ

๋ˆ„๋ฆฌ๋‹ฌ์ดํ‹€ 2021. 2. 10. 00:44

์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ Cloud Firestore์— ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ €์žฅ๋˜๋Š”์ง€ ์ „์ฒด์ ์ธ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด์•˜๋Š”๋ฐ์š”~!!

๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ž˜ ๋ชจ๋ฅด๋ฉด ๋จผ์ € ๊ตฌ์กฐ๋ถ€ํ„ฐ ํ™•์‹คํ•˜๊ฒŒ ์•Œ๊ณ  ์‹ค์Šต์„ ์‹œ์ž‘ํ•˜๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค ๐Ÿ‘๐Ÿ‘

๐Ÿ‘‰ 2021/02/08 - [iOS [Swift]/๊ธฐ์ดˆ๋ฅผ ํƒ„ํƒ„ํžˆ!] - [Swift] Cloud Firestore(1) ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ

 

์ด๋ฒˆ์—๋Š” ์‹ค์ œ๋กœ XCode์—์„œ ์–ด๋–ป๊ฒŒ Firestore๋ฅผ ํ†ตํ•ด CURD๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์‹ค์Šตํ•ด๋ณผ๊ฑฐ์—์š”.


๋จผ์ € ์‹ค์Šต์„ ์œ„ํ•ด์„œ, Firestore๋ฅผ ๋น„์–ด์žˆ๊ฒŒ ์ค€๋น„ํ•˜๊ณ , Console์„ ๋ฐ”๋กœ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์›Œ์ค์‹œ๋‹ค!

 

Database ์ฐธ์กฐ

๋ณธ๊ฒฉ CRUD ์‹ค์Šต์— ์•ž์„œ, ์šฐ๋ฆฌ๊ฐ€ Cloud์˜ Firestore์ด ์–ด๋””์žˆ๋Š”์ง€ ์œ„์น˜์ •๋ณด๋ฅผ ์•Œ์•„์•ผ CRUD๋ฅผ ์ง„ํ–‰ํ•˜๊ฒ ์ฃ ~?

์•„๋ž˜ ์ฝ”๋“œ๋กœ ์‹ค์ œ๋กœ Firestore ์ƒ์— ์šฐ๋ฆฌ์˜ DB์œ„์น˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์–ด์š”.

let db = Firestore.firestore()

 

๋ฐ์ดํ„ฐ ์ €์žฅ (Create)

๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ• ๋•Œ๋Š” ์ด์ „ ํฌ์ŠคํŒ…์—์„œ ์ •๋ฆฌํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ Collection์— Document๋ฅผ ๋งŒ๋“ค๊ณ , Document์— Data๋ฅผ ์ €์žฅํ•˜๋ฉด ๋˜๊ฒ ์ฃ ? Documenet๋ฅผ ๋งŒ๋“ค๋•Œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ Document ์ด๋ฆ„์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์ž๋™์œผ๋กœ ์ด๋ฆ„์„ ์ง€์–ด์ฃผ๋Š” Auto Generated ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์š”. ๋จผ์ € ๋ช…์‹œ์ ์œผ๋กœ "users"๋ผ๋Š” collection์— "userid123"์ด๋ผ๋Š” document๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ์•ˆ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด๋ณผ๊ฒŒ์š”.

db.collection("users").document("userid123").setData(["firstname":"Tom", "lastname":"Bee", "age":26])

์˜ค์˜ค~~๐Ÿ‘๐Ÿ‘ ์˜ˆ์ƒํ–ˆ๋˜ ๋Œ€๋กœ Firebase Console์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŒ๋“ค์–ด์ง„๊ฒŒ ๋ณด์ด๋„ค์š”. ์—ญ์‹œ ๋ˆˆ์— ๋ฐ”๋กœ๋ฐ”๋กœ ๋ณด์—ฌ์•ผ ์‰ฝ๊ฒŒ ์ดํ•ด๊ฐ€ ๋˜๊ณ  ํฅ๋ฏธ๊ฐ€ ์ƒ๊ธฐ๋Š” ๊ฒƒ ๊ฐ™์•„์š” ใ…Žใ…Ž ์—ฌ๊ธฐ์„œ ์ž๋™์œผ๋กœ ์ฝ˜์†”์ด ๊ฐฑ์‹ ์ด ์•ˆ๋˜๋ฉด ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•ด์ฃผ์„ธ์š” ~~

 

๋‹ค์Œ์œผ๋กœ, ์ž๋™์œผ๋กœ Document ์ด๋ฆ„์„ ์ง€์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํ•˜๋‚˜ ์ƒ์„ฑํ•ด๋ณผ๊ฒŒ์š”.

db.collection("users").addDocument(data: ["firstname":"Jay", "lastname":"Koo", "age":35])
// db.collection("users").document().setData(["firstname":"Jay", "lastname":"Koo", "age":35])

์ด๋ ‡๊ฒŒ addDocument Method๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•ด์ค„ ์ˆ˜๋„ ์žˆ๊ณ , document() ์ด๋ ‡๊ฒŒ ์ด๋ฆ„์„ ๋น„์›Œ๋‘๋ฉด ์ž๋™์œผ๋กœ ์ด๋ฆ„์„ ์ง€์–ด์ค€๋‹ต๋‹ˆ๋‹ค. ๋ฐ”๋กœ๋ฐ”๋กœ ์ž˜ ๋ฐ˜์˜์ด ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์ค๋‹ˆ๋‹ค~~ ๐ŸคŸ

์กฐ๊ธˆ๋งŒ ์‘์šฉํ•ด๋ณด๋ฉด, ์ด๋ ‡๊ฒŒ ํŠน์ • ๋ณ€์ˆ˜์— document๋ฅผ ํ• ๋‹นํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ฒ ๋„ค์š”. ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๊ธฐ๋„ ํ•˜๊ณ , ์—…๋ฐ์ดํŠธ๋„ ํ•˜๊ณ , ๊ทธ๋Ÿฌ๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์ž–์•„์š”~~ ใ…‹ใ…‹ ๊ทธ๋ฆฌ๊ณ  ์‚ด์ง๋งŒ ์ž์„ธํžˆ ๋ณด๋ฉด, "id"๋ผ๋Š” ํ•„๋“œ๋ฅผ documentID๋กœ ์ง€์ •ํ•ด์คฌ์–ด์š”. ์ด๋ ‡๊ฒŒ id๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ’์„ ์ •ํ•ด๋†“์œผ๋ฉด, ๋‹ค๋ฅธ collection์ด๋‚˜ document์—์„œ ์ฐธ์กฐํ• ๋•Œ ์“ฐ์ผ ์ˆ˜๋„ ์žˆ์–ด์š”. (๋งˆ์น˜ foreign key ๊ฐ™์ด์š”)

let myNewDoc = db.collection("users").document() // create new doc
myNewDoc.setData(["firstname":"John", "lastname":"Qoo", "age":30, "id": myNewDoc.documentID])

์‚ด์ง ๋Š๋‚Œ ์˜ค์‹œ๋‚˜์š”~? ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์œ„์™€ ๊ฐ™์ด id๋ฅผ documentId๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ง€์ •ํ•ด์ฃผ๊ณ , ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๊ฐ™์ด ์‹คํ–‰ํ•˜๋ฉด

db.collection("allergies").document(myNewDoc.documentID).setData(["allergies":"peanuts"])

John์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ users ์ปฌ๋ ‰์…˜์— ์ƒ๊ธฐ๊ณ , allergies ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“ค๋ฉด์„œ ํ•˜์œ„์˜ document ์ด๋ฆ„์„ ๋™์ผํ•˜๊ฒŒ ๋งž์ถฐ ์ค„ ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑํ•ด๋†“์œผ๋ฉด, John์€ ๋•…์ฝฉ ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ์‰ฝ๊ฒŒ ์ฐพ์•„๊ฐˆ ๋ฐฉ๋ฒ•์ด ์ƒ๊ธฐ๊ฒ ์ฃ ~?ใ…Žใ…Ž

 

 

๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ (Update)

์ด๋ฒˆ์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด๋ด…์‹œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์œ„์—์„œ ๋งŒ๋“  ๋ฐ์ดํ„ฐ์— userid123์˜ firstname์„ Mike๋กœ ๋ฐ”๊พธ๊ณ  ์‹ถ์–ด์š”.

db.collection("users").document("userid123").setData(["firstname":"Mike"])

ํ—‰.. firstname๋งŒ ์ƒˆ๋กœ ์ง€์ •ํ•ด์ฃผ๋ฉด ์—…๋ฐ์ดํŠธ ๋  ์ค„ ์•Œ์•˜๋Š”๋ฐ ๋‚ญํŒจ๋ฅผ ๋ดค์–ด์š”. ์›๋ž˜ ๋งŒ๋“ค์—ˆ๋˜ lastname, age๋Š” ์˜จ๋ฐ๊ฐ„๋ฐ ์—†๊ณ .. ใ… ใ…  ์ด๋ ‡๊ฒŒ setData๋ฅผ ๊ทธ๋ƒฅ ์‚ฌ์šฉํ•ด๋ฒ„๋ฆฌ๋ฉด Overwrite(๋ฎ์–ด์“ฐ๊ธฐ) ํ•ด๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ• ๋•Œ ์œ„ํ—˜ํ•˜๋‹ˆ ์กฐ์‹ฌํ•ด์•ผ๋˜์š”. ๐Ÿ˜

๊ทธ๋Ÿผ ์ •๋ง๋กœ ์—…๋ฐ์ดํŠธ๋Š” ์–ด๋–ป๊ฒŒ ํ• ๊นŒ์š”~?

db.collection("users").document("userid123").setData(["lastname":"Chang", "firstname":"Marly", "age":26], merge: true)

์ด๋ ‡๊ฒŒ setData๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด merge๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋ง ๊ทธ๋Œ€๋กœ Mergeํ•˜๋ฉด์„œ Overwrite ํ•˜๊ฒ ๋‹ค๋Š” ๊ฑฐ์—์š”! ์›๋ž˜ ์žˆ๋˜ ํ•„๋“œ๊ฐ’์€ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๊ณ , ์›๋ž˜ ์—†๋˜ ํ•„๋“œ๊ฐ’์€ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ๊ฐ€ ์ž˜ ๋˜์—ˆ๊ณ , ์ƒˆ๋กœ์šด ํ•„๋“œ๋„ ์ž˜ ์ƒ๊ฒผ๋„ค์š” ~~!! ๐Ÿ‘๐Ÿ‘ ๊ทธ๋ž˜๋„ setData๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑด.. ์–ธ์ œ๊นŒ์ง€๋‚˜ ๋งค์šฐ ์œ„ํ—˜ํ•œ ์š”์†Œ๋ฅผ ๋Š˜ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š”๊ฑฐ์—์š”. ํ˜น์‹œ๋ผ๋„ ์‹ค์ˆ˜๋กœ merge ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋น ๋œจ๋ ธ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด.. ๋„์•…! ์ด์ „์— ์ €์žฅ๋˜์žˆ๋˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ชจ๋‘ Overwrite๋ ๊ฑฐ์—์š” ๐Ÿ˜ญ

์‚ฌ์‹ค์€ setData๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์–ด์š”~ ํ•˜๊ณ  ์ •๋ฆฌํ•œ๊ฑฐ๊ตฌ์š”~!!ใ…‹ใ…‹

 

์‹ค์ œ๋กœ๋Š” updateData Method๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๐Ÿ˜„  ํŽธ - ์•ˆ..

๋ฌผ๋ก , ์žˆ๋Š” ํ•„๋“œ๋Š” ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๋ฉด์„œ ์ƒˆ๋กœ์šด ํ•„๋“œ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋Š” ์‹ ๊ทœ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ต๋‹ˆ๋‹ค~~

db.collection("users").document("userid123").updateData(["firstname":"sarah", "hair":"black"])

 

 

๋ฐ์ดํ„ฐ ์‚ญ์ œ (Delete)

์ด๋ฒˆ์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ ์‚ญ์ œํ•ด๋ณผ๊ฒŒ์š”! ๋จผ์ € document๋ฅผ ํ†ต์งธ๋กœ ์‚ญ์ œํ•˜๊ณ  ์‹ถ์–ด์š”. ์ด ์‚ฌ๋žŒ์ด ํšŒ์›ํƒˆํ‡ด๋ฅผ ํ•ด๋ฒ„๋ ธ์–ด์š”..๐Ÿ˜ญ

๊ทธ๋Ÿด๋•Œ๋Š” ์ด๋ ‡๊ฒŒ documentId๋ฅผ ๊ฐ€์ง€๊ณ  deleteํ•ด๋ฒ„๋ฆฌ๋ฉด ๋˜์š”! ๊ฐ„๋‹จํ•˜์ฅฌ~~?

db.collection("users").document("SepScv75QCfhd1rpaEeA").delete()

์‹ค์ œ๋กœ sep~~์–ด์ฉŒ๊ตฌ ํ•˜๋Š” document๊ฐ€ ์‚ญ์ œ๋˜์—ˆ์–ด์š”. ์Œ.. ์ข‹์•„! document๋Š” ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๊ฒ ์–ด. ๊ทผ๋ฐ ๋‚˜๋Š” ํšŒ์›์ •๋ณด์ค‘์— ํ•„๋“œ ํ•˜๋‚˜๋งŒ ์‚ญ์ œํ•˜๊ณ  ์‹ถ์€๋ฐ ์–ด๋–ป๊ฒŒ ํ•˜์ง€.. ๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“œ์…จ๋‹ค๋ฉด ์ •์ƒ์ž…๋‹ˆ๋‹ค!! ํ•„๋“œ ํ•˜๋‚˜๋งŒ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” updateData Method๋ฅผ ์‚ฌ์šฉํ•ด์ค˜์•ผ ํ•˜๋Š”๋ฐ์š”, ์ด๋ ‡๊ฒŒ ์‹ค์ œ value๊ฐ’์„ FieldValue.delete()๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ต๋‹ˆ๋‹ค! hair ํ•„๋“œ๊ฐ’ ํ•˜๋‚˜๋งŒ ์‚ญ์ œ์™„๋ฃŒ!๐Ÿ‘

db.collection("users").document("userid123").updateData(["hair":FieldValue.delete()])

 

 

Error Handling (์—๋Ÿฌ ํ•ธ๋“ค๋ง)

๋ฐ์ดํ„ฐ ์กฐํšŒํ•˜๊ธฐ์— ์•ž์„œ, ์šฐ๋ฆฌ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ/์—…๋ฐ์ดํŠธ/์‚ญ์ œ๋ฅผ ํ•˜๋Š”๋ฐ ํ˜ธ์˜ฅ~~์‹œ๋‚˜ ์‹คํŒจํ•  ์ˆ˜๋„ ์žˆ์ž–์•„์š”~~?

๊ทธ๋Ÿด๋•Œ ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•˜๋ผ๊ณ  ๋”ฐ๋กœ completion Handler๋ฅผ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์œ„์—์„œ ๋ฐ์ดํ„ฐ ์ €์žฅ์‹œ ์‚ฌ์šฉํ–ˆ๋˜ addDocument ๋ฉ”์†Œ๋“œ๋„ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ณตํ•ด์š”.

db.collection("users").addDocument(data: [:]) { error in
            // this code is run after the operation is complete
            if error == nil {
                // operation success
            } else {
                // error, do something
            }
        }

๋ฌผ๋ก  setData, update, delete ๋ชจ๋‘ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ Completion Handler๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ต๋‹ˆ๋‹ค.

db.collection("users").document("userid123").setData([:], merge: true) { (error) in
            // this code is run after the operation is complete
            if error == nil {
                // operation success
            } else {
                // error, do something
            }
        }

 

 

๋ฐ์ดํ„ฐ ์กฐํšŒ (Read)

firestore database ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š”๊ฒƒ์€ push๋ฐฉ์‹๊ณผ pull๋ฐฉ์‹์ด ์žˆ์–ด์š”. pull๋ฐฉ์‹์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ db์— ๋ญ”๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•ด์„œ ๋ฐ›๋Š”๊ฑฐ๊ณ  push๋ฐฉ์‹์€ ๋ฐ์ดํ„ฐ ๋ณ€๋™์ด ์žˆ์œผ๋ฉด db์—์„œ ์•Œ์•„์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด์ฃผ๋Š” ๋ฐฉ์‹์ด์—์š”.

 

๋จผ์ € pull ๋ฐฉ์‹์€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ๊ฑฐ์—์š”. ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ• ๋•Œ getDocument Method๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๋Š”๋ฐ์š”~!

 

ํŠน์ • document ๋ฅผ ์กฐํšŒํ•˜๊ธฐ (pull)

์ด๋ ‡๊ฒŒ ์ž๋™์™„์„ฑ๊ธฐ๋Šฅ์—์„œ ์„ค๋ช…์„ ๋ณด๋ฉด, ํŠน์ • document๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ ๋ฆฌํ„ด๋ฐ›๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด FIRDocumentSnapshotBlock ์ด๋„ค์š”! ์—ฌ๊ธฐ์„œ ์ด ํƒ€์ž…์— ํ•œ๋ฒˆ ์ฃผ๋ชฉํ•ด๋ณผ๊ฒŒ์š”. ์ด ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ DocumentSnapshot(์‹ค์ œ ์ถ”์ถœํ•œ ๋ฐ์ดํ„ฐ)์™€, Error(์—๋Ÿฌ)๋กœ ๊ตฌ์„ฑ๋˜์š”. ์˜๋ฏธ ๊ทธ๋Œ€๋กœ DocumentSnapshot์€ document ํ•˜๋‚˜๋ฅผ ์˜๋ฏธํ•˜๋Š”๊ฑฐ์—์š”.๐Ÿ‘

 

์˜ˆ๋ฅผ ๋“ค๋ฉด ์ด๋ ‡๊ฒŒ userid123์— ๋Œ€ํ•œ document๋ฅผ ์š”์ฒญํ•˜๊ณ , ๋ฆฌํ„ด๋ฐ›์€ ๋ฐ์ดํ„ฐ(snapshot)์„ ๋ณด๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์ €์žฅํ–ˆ๋˜ userid123์— ๋Œ€ํ•œ data๊ฐ€ ์ œ๋Œ€๋กœ ๋‚ด๋ ค์™”์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”!

db.collection("users").document("userid123").getDocument { (snapshot, error) in
            if error == nil && snapshot != nil && snapshot!.data() != nil {
                print(snapshot!.data())
            }
        }

 

collection์•ˆ์—์žˆ๋Š” ๋ชจ๋“  document๋“ค์„ ์กฐํšŒํ•˜๊ธฐ (pull)

์ด๋ฒˆ์—๋Š” ํŠน์ • document๊ฐ€ ์•„๋‹ˆ๋ผ, ์กด์žฌํ•˜๋Š” ๋ชจ๋“  document๋ฅผ ์กฐํšŒํ•ด๋ณผ๊ฑฐ์—์š”. ๋™์ผํ•˜๊ฒŒ getDocuments๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ ์ด๋ฒˆ์—๋Š” collection์—์„œ ๋ฐ”๋กœ getDocuments๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋„ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์—์„œ ํ•œ๋ฒˆ ์„ค๋ช…์„ ๋ณผ๊นŒ์š”?

์˜ค! ์ด๋ฒˆ์—๋Š” ์•„๊นŒ์™€ ์•ฝ~๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด FIRQuerySnapshotBlock ์ด๋„ค์š”! ์ด ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ QuerySnapshot(์‹ค์ œ ์ถ”์ถœํ•œ ๋ฐ์ดํ„ฐ), Error(์—๋Ÿฌ)๋กœ ๊ตฌ์„ฑ๋˜์š”. ์ด๋ฒˆ์—๋Š” Query๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ snapshot์œผ๋กœ, ๋ชจ๋“  documents๋“ค์„ Arrayํ˜•ํƒœ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”. snapshot.documents๋กœ ํ•ด๋‹น array์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

db.collection("users").getDocuments { (snapshot, error) in
            if error == nil && snapshot != nil {
                for document in snapshot!.documents {
                    print(document.documentID)
                }
            } else {
                // error. do something
            }
        }

์‹ค์ œ๋กœ firestore์— ์ €์žฅ๋œ document์˜ ID๋“ค์ด ์ž˜ ์ถœ๋ ฅ๋˜์—ˆ๋„ค์š”~!!

 

์ž˜ ๋”ฐ๋ผ์˜ค๊ณ  ๊ณ„์‹œ์ฃ ? ๐Ÿ™ ์กฐ๊ธˆ์€ ์ƒ์†Œํ•  ์ˆ˜ ์žˆ์–ด์š”! ๊ทธ์น˜๋งŒ ์œ„์—์„œ pull ๋ฐฉ์‹์— ๋Œ€ํ•œ ๋ฆฌํ„ด๋ฐ์ดํ„ฐ ํƒ€์ž…๋งŒ ์ž˜ ์ดํ•ดํ•˜์…จ์œผ๋ฉด push๋ฐฉ์‹์€ ์ •๋ง ๋ฐฉ์‹๋งŒ ๋‹ค๋ฅผ ๋ฟ ์™„์ „ํžˆ ๋™์ผํ•˜๋‹ต๋‹ˆ๋‹ค ๐ŸคŸ๐ŸคŸ

 

ํŠน์ • document ๋ฅผ ์กฐํšŒํ•˜๊ธฐ (push)

์œ„์—์„œ ํ–ˆ๋˜ ๊ฒƒ๊ณผ ๊ฑฐ์˜ ๋™์ผํ•œ๋ฐ ํ˜ธ์ถœํ•˜๋Š” Method๋งŒ addSnapshotListener๋กœ ๋ฐ”๋€Œ์—ˆ์ฃ ??

์•„๊นŒ๋Š” ์šฐ๋ฆฌ๊ฐ€ db๋กœ "์•ผ ์ด๊ฑฐ ๋ฐ์ดํ„ฐ ์ค˜!" ๋ผ๊ณ  ์š”์ฒญํ•ด์„œ ๋ฐ›์•˜๋‹ค๋ฉด, ์ด๋ฒˆ์—๋Š” db์—์„œ ์šฐ๋ฆฌ์—๊ฒŒ "์•ผ ์ด๊ฑฐ ๋ฐ์ดํ„ฐ ๋ณ€๋™์žˆ์œผ๋‹ˆ๊นŒ ์ค€๋‹ค. ํ• ๊ฑฐ ์žˆ์œผ๋ฉด ์•Œ์•„์„œ ์ฒ˜๋ฆฌํ•ด!" ๋ผ๊ณ  ํ•˜๋Š” ๋ฐฉ์‹์ด์—์š”. ์ •๋ง ์ด๊ฒƒ๋งŒ ๋‹ฌ๋ผ์š” ๐Ÿ˜Ž

let listener = db.collection("users").document("userid123").addSnapshotListener { (snapshot, error) in
            if error == nil && snapshot != nil && snapshot!.data() != nil {
                print(snapshot!.data())
            }
        }

์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๊ฐ€ ์žˆ์œผ๋ฉด userid123์ด๋ผ๋Š” document ์•ˆ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€/์—…๋ฐ์ดํŠธ/์‚ญ์ œ ๋˜๋ฉด ์ € print() ๊ตฌ๋ฌธ์ด ์‹คํ–‰๋˜๋Š”๊ฑฐ์—์š”. print()์— ์ค‘๋‹จ์ ์„ ๊ฑธ๊ณ  ๋””๋ฒ„๊น…ํ•ด๋ณด๋ฉด ์ตœ์ดˆ์— ํ•œ๋ฒˆ(์ดˆ๊ธฐ db๋ฐ์ดํ„ฐ ์ƒํƒœ๋ฅผ ์ฝ์–ด์˜ค๋Š”๊ณผ์ •) ํ˜ธ์ถœ์ด ๋˜๊ณ , ๊ทธ ๋‹ค์Œ๋ถ€ํ„ฐ๋Š” ๋ณ€๋™์ด ์žˆ์„๋•Œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด์ค€๋‹ต๋‹ˆ๋‹ค. ํ•œ๋ฒˆ Console์—์„œ ๋ญ”๊ฐ€ ์‚ญ์ œ/์—…๋ฐ์ดํŠธ/์ถ”๊ฐ€๋ฅผ ์ง์ ‘ ํ•ด๋ณด์‹œ๊ธธ ์ถ”์ฒœ๋“œ๋ ค์š” ๐Ÿ‘๐Ÿ‘

 

collection์•ˆ์—์žˆ๋Š” ๋ชจ๋“  document๋“ค์„ ์กฐํšŒํ•˜๊ธฐ (push)

์œ„์—์„œ๋Š” ํŠน์ • document ๋‚ด์˜ ๋ฐ์ดํ„ฐ ๋ณ€ํ™”์— ๋Œ€ํ•ด Push๋ฅผ ๋ฐ›์•˜๋‹ค๋ฉด, ์ด๋ฒˆ์—๋Š” ์ „์ฒด collection ๋‚ด์—์„œ ๋ณ€๋™์ด ์ƒ๊ธฐ๋ฉด push๋ฅผ ๋ฐ›์„ ๋ฟ, ์œ„์™€ ์™„์ „ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜‡๐Ÿ˜‡

๋‹ค..๋‹ค๋งŒ... ํ•œ๊ฐ€์ง€.. ์•Œ๊ณ  ์žˆ์œผ๋ฉด ์ข‹์€ ์ ์ด ์žˆ์–ด์š”. ๋˜‘๊ฐ™์ด snapshot.documents๋กœ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์„œ.. Loop๋ฅผ ๋Œ๋ฉด์„œ ๋ณ€ํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์•„์„œ ๋ญ”๊ฐ€ Action์„ ํ•˜๊ธฐ์—”, ๋ณ€ํ™”๊ฐ€ ์—†๋Š” ๋ฉ€์ฉกํ•œ data๋“ค์„ ๋ชจ๋‘ Loopํ•˜๊ธฐ์— ๋„ˆ๋ฌด ๋น„ํšจ์œจ์ ์ด์ฃ  ๐Ÿ˜ญ

๊ทธ๋ž˜์„œ ์ด๋•Œ๋Š” ๋ณ€ํ™”๊ฐ€ ์‹ค์ œ๋กœ ๋ฐœ์ƒํ•œ document๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด์š”. snapshot.documentChanges๋ฅผ ์‚ฌ์šฉํ•ด์„œ์š”!

let listener = db.collection("users").addSnapshotListener { (snapshot, error) in
            if error == nil && snapshot != nil {

                // ๋ณ€ํ™”๊ฐ€ ์žˆ๋Š”๊ฒƒ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
                for change in snapshot!.documentChanges {
                    print(change.document.documentID)
                }
            } else {
                // error. do something
            }
        }

 

 

Query

์ง€๊ธˆ๊นŒ์ง€๋Š”..ใ…Žใ…Ž ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด๋ดค๋Š”๋ฐ์š”~! ํŠน์ •์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์‹ถ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”?

SQL์„ ์˜ˆ๋กœ ๋“ค๋ฉด SELECT, FROM์€ ๋ชจ๋‘ ๋์ฃ ~~? ๊ทธ๋Ÿฐ๋ฐ.. WHERE์ ˆ์€ ์–ด๋–ป๊ฒŒ ํ•œ๋‹จ ๋ง์ธ๊ฐ€.. ๐Ÿ˜ญ

์—ฌ๊ธฐ์„œ๋„ ๋™์ผํ•˜๊ฒŒ where์ ˆ ์กฐ๊ฑด์„ ๋„ฃ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Query๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ๋ฐ”๋กœ whereField๋ฅผ ์‚ฌ์šฉํ•ด์„œ์š”~!

๋ฐ”๋กœ ์˜ˆ์‹œ๋ฅผ ๋ณด๋„๋ก ํ• ๊ป˜์š”~~

let query = db.collection("users").whereField("age", isEqualTo: 30)
        query.getDocuments { (snapshot, error) in
            let docs = snapshot!.documents

            for doc in docs {
                print(doc.documentID)
            }
        }

users collection ์•ˆ์—์„œ age๊ฐ€ 30์ธ๊ฒƒ๋“ค์˜ document๋“ค์„ ๊ฐ€์ ธ์™€๋ผ!

 

let query = db.collection("users").whereField("lastname", in: ["Harry", "chang"])
        query.getDocuments { (snapshot, error) in
            let docs = snapshot!.documents

            for doc in docs {
                print(doc.documentID)
            }
        }

users collection ์•ˆ์—์„œ lastname์ด in: [ ] ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” document๋“ค์„ ๊ฐ€์ ธ์™€๋ผ!

 

let query = db.collection("users").whereField("pets", arrayContains: "dog")
        query.getDocuments { (snapshot, error) in
            let docs = snapshot!.documents

            for doc in docs {
                print(doc.documentID)
            }
        }

users collection ์•ˆ์—์„œ pets๋ผ๋Š” array์•ˆ์— "dog"๊ฐ€ ์žˆ๋Š” document๋“ค์„ ๊ฐ€์ ธ์™€๋ผ! (arrayContains๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ Field์˜ ํƒ€์ž…์ด Array์ด์–ด์•ผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค!)

 

let query = db.collection("users").whereField("pets", arrayContainsAny: ["dog", "lion"]) // ์ด๊ฑฐ์ค‘ ์•„๋ฌด๊ฑฐ๋‚˜ ์žˆ๋Š”์‚ฌ๋žŒ.
        query.getDocuments { (snapshot, error) in
            let docs = snapshot!.documents

            for doc in docs {
                print(doc.documentID)
            }
        }

users collection ์•ˆ์—์„œ pets๋ผ๋Š” array์•ˆ์— [ ] ์•ˆ์— ์žˆ๋Š” ๊ฒƒ์ค‘ ์•„๋ฌด๊ฑฐ๋‚˜ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” document๋ฅผ ๊ฐ€์ ธ์™€๋ผ! (๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐ˜๋“œ์‹œ Field์˜ ํƒ€์ž…์ด Array์ด์–ด์•ผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค!)

 

let query = db.collection("users").whereField("pets", arrayContainsAny: ["dog", "lion"]).whereField("age", isEqualTo: 30)
        query.getDocuments { (snapshot, error) in
            let docs = snapshot!.documents

            for doc in docs {
                print(doc.documentID)
            }
        }

์ด๋ ‡๊ฒŒ Query๋ฅผ ์ค‘์ฒฉํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์–ด์š”! users collection ์•ˆ์—์„œ pets๋ผ๋Š” array์•ˆ์— [ ] ์•ˆ์— ์žˆ๋Š” ๊ฒƒ์ค‘ ์•„๋ฌด๊ฑฐ๋‚˜ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด์„œ age๊ฐ€ 30์ธ document๋“ค์„ ๊ฐ€์ ธ์™€๋ผ!

 

๊ฐ„๋‹จํ•œ Query๋“ค๊นŒ์ง€ ์‚ด์ง ์‚ดํŽด๋ณด์•˜๋Š”๋ฐ์š”~!

firestore๊ฐ€ Indexing๋„ ์ง€์›ํ•ด์„œ ๋น ๋ฅด๊ฒŒ ์ฟผ๋ฆฌ๋ฅผ ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ๋Š” ๋ฐ˜๋ฉด์—, ์•ฝ๊ฐ„ ์•„์‰ฌ์šด ์ ๋“ค๋„ ์žˆ์Šต๋‹ˆ๋‹ค

  • ์˜ˆ๋ฅผ ๋“ค๋ฉด "!=" ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ• ์ˆ˜ ์—†๋‹ค๋Š” ์ 
  • ์ค‘์ฒฉํ•ด์„œ ์‚ฌ์šฉํ• ๋•Œ isLessThan, isGreaterThan ๋“ฑ ํฌ๊ธฐ๋น„๊ต ์—ฐ์‚ฐ์€ ํ•˜๋‚˜์˜ ํ•„๋“œ๊ฐ’์— ๋Œ€ํ•ด์„œ๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ 
  • arrayContains, arrayContainsAny๋Š” ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ 

 

๋Œ€ํ‘œ์ ์œผ๋กœ ์œ„์™€ ๊ฐ™์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์กฐ๊ธˆ ๋” ์žˆ์–ด์š”. 

firebase.google.com/docs/firestore/query-data/queries

 

Cloud Firestore์—์„œ ๋‹จ์ˆœ ์ฟผ๋ฆฌ ๋ฐ ๋ณตํ•ฉ ์ฟผ๋ฆฌ ์‹คํ–‰  |  Firebase

Cloud Firestore๋Š” ์ปฌ๋ ‰์…˜ ๋˜๋Š” ์ปฌ๋ ‰์…˜ ๊ทธ๋ฃน์—์„œ ๊ฒ€์ƒ‰ํ•  ๋ฌธ์„œ๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ์ฟผ๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ์— ์„ค๋ช…๋œ ๋Œ€๋กœ ์ด๋Ÿฌํ•œ ์ฟผ๋ฆฌ๋ฅผ get() ๋˜๋Š” addS

firebase.google.com

์ง์ ‘ ์‹ค์Šตํ•ด๋ณด๋ฉฐ ๊ฐ„๋‹จํ•œ CRUD์™€ Query๋ฅผ ์‚ดํŽด๋ณด์•˜๋Š”๋ฐ์š”~!! ์‹ค์ œ๋กœ๋Š” ๋‹ค์–‘ํ•œ Query ์กฐ๊ฑด์ด ์žˆ๊ณ , ์ •๋ ฌ, ์ œํ•œ์‚ฌํ•ญ ๋“ฑ๋“ฑ ํ™•์žฅํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์ •๋ง ๋งŽ๋‹ต๋‹ˆ๋‹ค!! ์œ„์˜ ๊ณต์‹ ๊ฐ€์ด๋“œ๋„ ๋งค์šฐ๋งค์šฐ ์ž˜ ์ •๋ฆฌ๋˜์–ด ์žˆ์œผ๋‹ˆ, ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค ๐Ÿ™

 

 

๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ๊ธด ํฌ์ŠคํŒ…์ด ๋˜์—ˆ๋„ค์š” ๐Ÿ˜Ž 

์–ธ์  ๊ฐ€, ๋ˆ„๊ตฐ๊ฐ€์—๊ฒ ๊ผญ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹น ๐Ÿค™๐Ÿค™

 

 

'iOS [Swift] > ๊ธฐ์ดˆ๋ฅผ ํƒ„ํƒ„ํžˆ!' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Swift] Codable  (0) 2021.02.26
[Swift] CodingKey  (0) 2021.02.26
[Swift] Cloud Firestore(1) ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ  (1) 2021.02.08
[Swift] ScrollView + PageControl  (0) 2021.02.05
[Swift] CGRect, CGSize, CGPoint  (0) 2021.02.05
Comments