이 빠른 시작에서는 Cloud Firestore를 설정하고 데이터를 추가한 후 핵심 작업 또는 파이프라인 작업을 사용하여 Firebase Console에서 방금 추가한 데이터를 쿼리하는 방법을 보여줍니다.
Cloud Firestore 데이터베이스 만들기
- Firebase 프로젝트를 아직 만들지 않았다면 Firebase Console에서 프로젝트 추가를 클릭한 후 화면에 표시된 안내를 따라 Firebase 프로젝트를 만들거나 기존 Google Cloud 프로젝트에 Firebase 서비스를 추가합니다.
Firebase Console에서 프로젝트를 엽니다. 왼쪽 패널에서 빌드를 펼친 다음 Firestore 데이터베이스를 선택합니다.
데이터베이스 만들기를 클릭합니다.
데이터베이스 모드로 Enterprise를 선택합니다.
작업 모드로 Native 모드의 Firestore를 선택합니다. 이 모드는 핵심 작업과 파이프라인 작업을 지원합니다.
데이터베이스의 위치를 선택합니다.
Cloud Firestore Security Rules의 시작 모드를 선택합니다.
- 테스트 모드
모바일 및 웹 클라이언트 라이브러리를 시작할 때 유용하지만 모든 사용자가 데이터를 읽고 덮어쓸 수 있습니다. 테스트 완료 후 데이터 보안 섹션을 검토해야 합니다.
웹, Apple 플랫폼 또는 Android SDK를 시작하려면 테스트 모드를 선택하세요.
- 프로덕션 모드
모바일 및 웹 클라이언트의 모든 읽기 및 쓰기를 거부합니다. 인증된 애플리케이션 서버(Python)에서는 사용자의 데이터베이스에 계속 액세스할 수 있습니다.
Cloud Firestore Security Rules의 초기 집합이 기본 Cloud Firestore 데이터베이스에 적용됩니다. 프로젝트에 데이터베이스를 여러 개 만드는 경우 각 데이터베이스에 Cloud Firestore Security Rules를 배포할 수 있습니다.
만들기를 클릭합니다.
Cloud Firestore를 사용 설정하면 Cloud API Manager의 API도 사용 설정됩니다.
개발 환경 설정
필요한 종속 항목 및 클라이언트 라이브러리를 앱에 추가하세요.
Web
- 안내에 따라 Firebase를 웹 앱에 추가합니다.
-
비공개 프리뷰용 Cloud Firestore SDK는 npm 패키지로 제공됩니다.
다음 명령어를 사용하여 npm 프로젝트에 Firestore SDK를 설치합니다.
npm install --save firebase@eap-firestore-pipelines
iOS+
- 안내에 따라 Firebase를 iOS 앱에 추가합니다.
- GitHub에서 Firebase SDK를 클론하고 파이프라인 브랜치를 확인합니다. 다음 단계에서 필요하므로 클론한 위치를 기록해 둡니다.
git clone https://github.com/firebase/firebase-ios-sdk.git # or git clone git@github.com:firebase/firebase-ios-sdk.git cd firebase-ios-sdk # check out pipeline feature branch git fetch origin feat/pipeline/private-preview git checkout feat/pipeline/private-preview
- 그런 다음 디렉터리(firebase-ios-sdk)를 Xcode 프로젝트에 로컬 종속 항목으로 추가합니다.
- 파일 메뉴에서 패키지 종속 항목 추가를 선택합니다.
- 로컬 추가… 버튼을 클릭한 다음 확인한 기능 브랜치가 있는 firebase-ios-sdk 디렉터리를 찾습니다.
Android
- 안내에 따라 Firebase를 Android 앱에 추가합니다.
- GitHub에서 Firebase SDK를 클론하고 파이프라인 브랜치를 확인한 후 로컬 Maven에 게시합니다.
# Prerequisites before you start: # Install Java 17 # Setup Android Development environments (having proper ANDROID_HOME, etc) git clone https://github.com/firebase/firebase-android-sdk.git # or git clone git@github.com:firebase/firebase-android-sdk.git cd firebase-android-sdk # check out pipeline feature branch git fetch origin feat/pipeline/private-preview git checkout feat/pipeline/private-preview # publish firebase SDK (without crashlytics) to maven local ./gradlew publishToMavenLocal -x :firebase-crashlytics:publishToMavenLocal -x :firebase-crashlytics-ndk:publishToMavenLocal # Optionally, if you want crashlytics built and published to mavel local # Make sure you have Android NDK 21 installed git submodule update --init --recursive ./gradlew publishToMavenLocal
- 프로젝트 수준 settings.gradle.kts에
mavenLocal을 추가합니다.dependencyResolutionManagement { repositories { mavenLocal() // Add this line .. } }
- 그런 다음 SDK의 로컬 버전을 추가합니다.
... // Firestore 99.0.0-pipeline.preview.1 has pipelines implementation("com.google.firebase:firebase-firestore:99.0.0-pipeline.preview.1") // Firebase Authentication implementation("com.google.firebase:firebase-auth") ...
Python
- Firestore Python SDK를 클론하고 파이프라인 프리뷰 브랜치를 확인합니다.
git clone https://github.com/googleapis/python-firestore.git # or git clone git@github.com:googleapis/python-firestore.git cd python-firestore # check out pipeline preview branch git fetch origin pipeline-preview git checkout pipeline-preview
- 로컬 python-firestore 서버 SDK를 설치합니다.
python -m pip install -e .
- 평소와 같이 Firebase Python Admin SDK를 설치합니다.
pip install --user firebase-admin
Cloud Firestore 초기화
Cloud Firestore의 인스턴스를 초기화합니다.
Web
import { initializeApp } from "firebase/app"; import { getFirestore } from "firebase/firestore"; // TODO: Replace the following with your app's Firebase project configuration // See: https://support.google.com/firebase/answer/7015592 const firebaseConfig = { FIREBASE_CONFIGURATION }; // Initialize Firebase const app = initializeApp(firebaseConfig); // When initializing Firestore, remember to use the name of the database you created earlier: const db = initializeFirestore(app, {}, 'your-new-enterprise-database');
FIREBASE_CONFIGURATION을 웹 앱의 firebaseConfig로 바꿉니다.
기기의 연결이 끊겨도 데이터를 유지하려면 오프라인 데이터 사용 설정 문서를 참조하세요.
Swift
import FirebaseCore import FirebaseFirestore FirebaseApp.configure() // When initializing Firestore, remember to use the name of the database you created earlier: let db = Firestore.firestore(database: "your-new-enterprise-database")
Kotlin
// Access a Cloud Firestore instance from your Activity // When initializing Firestore, remember to use the name of the database you created earlier: val firestore = FirebaseFirestore.getInstance("your-new-enterprise-database")
Java
// Access a Cloud Firestore instance from your Activity // When initializing Firestore, remember to use the name of the database you created earlier: FirebaseFirestore firestore = FirebaseFirestore.getInstance("your-new-enterprise-database");
Python
Admin SDK를 사용하여 엔터프라이즈 데이터베이스로 인증합니다.
import firebase_admin from firebase_admin import firestore def main(): default_app = firebase_admin.initialize_app() client = firestore.client(default_app, "your-new-enterprise-database") query = client.pipeline().database().limit(5) for result in query.execute(): print(result.data()) if __name__ == "__main__": main()
핵심 작업을 사용하여 데이터 추가
데이터 쿼리를 위한 핵심 작업 및 파이프라인 작업을 탐색하려면 핵심 작업을 사용하여 데이터베이스에 데이터를 추가합니다.
Cloud Firestore는 컬렉션에 저장되는 문서에 데이터를 저장합니다. 문서에 데이터를 처음 추가할 때 Cloud Firestore는 암시적으로 컬렉션과 문서를 만듭니다. 컬렉션이나 문서를 명시적으로 만들 필요가 없습니다.
다음 예시 코드를 사용해 새 컬렉션과 문서를 만듭니다.
Web
import { collection, addDoc } from "firebase/firestore"; try { const docRef = await addDoc(collection(db, "users"), { first: "Ada", last: "Lovelace", born: 1815 }); console.log("Document written with ID: ", docRef.id); } catch (e) { console.error("Error adding document: ", e); }
Web
db.collection("users").add({ first: "Ada", last: "Lovelace", born: 1815 }) .then((docRef) => { console.log("Document written with ID: ", docRef.id); }) .catch((error) => { console.error("Error adding document: ", error); });
Swift
// Add a new document with a generated ID do { let ref = try await db.collection("users").addDocument(data: [ "first": "Ada", "last": "Lovelace", "born": 1815 ]) print("Document added with ID: \(ref.documentID)") } catch { print("Error adding document: \(error)") }
Kotlin
// Create a new user with a first and last name val user = hashMapOf( "first" to "Ada", "last" to "Lovelace", "born" to 1815, ) // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener { documentReference -> Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}") } .addOnFailureListener { e -> Log.w(TAG, "Error adding document", e) }
Java
// Create a new user with a first and last name Map<String, Object> user = new HashMap<>(); user.put("first", "Ada"); user.put("last", "Lovelace"); user.put("born", 1815); // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId()); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.w(TAG, "Error adding document", e); } });
Python
이제 users 컬렉션에 다른 문서를 추가합니다. 첫 번째 문서에는 나타나지 않는 키-값 쌍(중간 이름)이 문서에 포함된다는 점에 유의하세요. 컬렉션의 문서에는 다른 정보 집합이 포함될 수 있습니다.
Web
// Add a second document with a generated ID. import { addDoc, collection } from "firebase/firestore"; try { const docRef = await addDoc(collection(db, "users"), { first: "Alan", middle: "Mathison", last: "Turing", born: 1912 }); console.log("Document written with ID: ", docRef.id); } catch (e) { console.error("Error adding document: ", e); }
Web
// Add a second document with a generated ID. db.collection("users").add({ first: "Alan", middle: "Mathison", last: "Turing", born: 1912 }) .then((docRef) => { console.log("Document written with ID: ", docRef.id); }) .catch((error) => { console.error("Error adding document: ", error); });
Swift
// Add a second document with a generated ID. do { let ref = try await db.collection("users").addDocument(data: [ "first": "Alan", "middle": "Mathison", "last": "Turing", "born": 1912 ]) print("Document added with ID: \(ref.documentID)") } catch { print("Error adding document: \(error)") }
Kotlin
// Create a new user with a first, middle, and last name val user = hashMapOf( "first" to "Alan", "middle" to "Mathison", "last" to "Turing", "born" to 1912, ) // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener { documentReference -> Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}") } .addOnFailureListener { e -> Log.w(TAG, "Error adding document", e) }
Java
// Create a new user with a first, middle, and last name Map<String, Object> user = new HashMap<>(); user.put("first", "Alan"); user.put("middle", "Mathison"); user.put("last", "Turing"); user.put("born", 1912); // Add a new document with a generated ID db.collection("users") .add(user) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId()); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.w(TAG, "Error adding document", e); } });
Python
핵심 작업을 사용하여 데이터 읽기
Firebase Console의 데이터 뷰어를 사용하여 Cloud Firestore에 추가한 데이터를 빠르게 확인합니다.
'get' 메서드를 사용해 전체 컬렉션을 가져올 수도 있습니다.
Web
import { collection, getDocs } from "firebase/firestore"; const querySnapshot = await getDocs(collection(db, "users")); querySnapshot.forEach((doc) => { console.log(`${doc.id} => ${doc.data()}`); });
Web
db.collection("users").get().then((querySnapshot) => { querySnapshot.forEach((doc) => { console.log(`${doc.id} => ${doc.data()}`); }); });
Swift
do { let snapshot = try await db.collection("users").getDocuments() for document in snapshot.documents { print("\(document.documentID) => \(document.data())") } } catch { print("Error getting documents: \(error)") }
Kotlin
db.collection("users") .get() .addOnSuccessListener { result -> for (document in result) { Log.d(TAG, "${document.id} => ${document.data}") } } .addOnFailureListener { exception -> Log.w(TAG, "Error getting documents.", exception) }
Java
db.collection("users") .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { Log.d(TAG, document.getId() + " => " + document.getData()); } } else { Log.w(TAG, "Error getting documents.", task.getException()); } } });
Python
users_ref = db.collection("users") docs = users_ref.stream() for doc in docs: print(f"{doc.id} => {doc.to_dict()}")
파이프라인 작업을 사용하여 데이터 읽기
이제 파이프라인 쿼리 환경을 핵심 쿼리 환경과 비교할 수 있습니다.
Web
const readDataPipeline = db.pipeline() .collection("users"); // Execute the pipeline and handle the result try { const querySnapshot = await execute(readDataPipeline); querySnapshot.results.forEach((result) => { console.log(`${result.id} => ${result.data()}`); }); } catch (error) { console.error("Error getting documents: ", error); }
Swift
do { // Initialize a Firestore Pipeline instance and specify the "users" collection as the // input stage. let snapshot = try await db.pipeline() .collection("users") .execute() // Execute the pipeline to retrieve documents. // Iterate through the documents in the pipeline results, similar to a regular query // snapshot. for result in snapshot.results { print("\(result.id ?? "no ID") => \(result.data)") } } catch { print("Error getting documents with pipeline: \(error)") }
Kotlin
val readDataPipeline = db.pipeline() .collection("users") // Execute the pipeline and handle the result readDataPipeline.execute() .addOnSuccessListener { result -> for (document in result) { println("${document.getId()} => ${document.getData()}") } } .addOnFailureListener { exception -> println("Error getting documents: $exception") }
Java
Pipeline readDataPipeline = db.pipeline() .collection("users"); readDataPipeline.execute() .addOnSuccessListener(new OnSuccessListener<Pipeline.Snapshot>() { @Override public void onSuccess(Pipeline.Snapshot snapshot) { for (PipelineResult result : snapshot.getResults()) { System.out.println(result.getId() + " => " + result.getData()); } } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { System.out.println("Error getting documents: " + e); } });
Python
pipeline = client.pipeline().collection("users") for result in pipeline.execute(): print(f"{result.id} => {result.data()}")
데이터 보안
웹, Android 또는 Apple 플랫폼 SDK를 사용하는 경우 Firebase 인증 및 Cloud Firestore Security Rules를 사용하여 Cloud Firestore의 데이터에 보안을 적용합니다.
다음은 시작하는 데 사용할 수 있는 기본 규칙 세트입니다. Console의 규칙 탭에서 보안 규칙을 수정할 수 있습니다.
인증 필요
// Allow read/write access to a document keyed by the user's UID
service cloud.firestore {
match /databases/{database}/documents {
match /users/{uid} {
allow read, write: if request.auth != null && request.auth.uid == uid;
}
}
}
프로덕션 모드
// Deny read/write access to all users under any conditions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
웹, Android 또는 iOS 앱을 프로덕션에 배포하기 전에 앱 클라이언트만 Cloud Firestore 데이터에 액세스할 수 있도록 하는 단계를 수행합니다. 앱 체크 문서를 참조하세요.
서버 SDK 중 하나를 사용하는 경우 Identity and Access Management(IAM)를 사용하여 Cloud Firestore의 데이터에 보안을 적용합니다.
다음 단계
다음 주제를 통해 핵심 및 파이프라인 작업에 대해 자세히 알아보세요.
- 핵심 작업과 파이프라인 작업의 차이점 숙지하기
- 핵심 작업으로 쿼리하는 방법 자세히 알아보기
- 파이프라인 작업으로 쿼리하는 방법 자세히 알아보기