앱에서 Firebase Realtime Database와 Cloud Firestore를 모두 사용하고 필요에 맞게 각 데이터베이스 솔루션의 이점을 활용할 수 있습니다. 예를 들어 Cloud Firestore의 접속 상태 구현에 설명된 대로 Realtime Database의 접속 상태 지원을 활용할 수 있습니다.
데이터베이스 간 차이점을 자세히 알아보세요.
Cloud Firestore로 데이터 이동
Realtime Database에서 Cloud Firestore로 일부 데이터를 마이그레이션하려는 경우 다음과 같은 진행 절차를 고려해 보세요. 데이터베이스마다 고유한 요구사항과 구조적 고려사항이 있기 때문에 이전 경로가 자동화되어 제공되지는 않습니다. 대신 이 같은 일반적인 진행 절차를 따르면 됩니다.
데이터 구조 및 보안 규칙을 Realtime Database에서 Cloud Firestore로 매핑합니다. Realtime Database와 Cloud Firestore는 모두 Firebase 인증을 사용하므로 앱의 사용자 인증을 변경할 필요가 없습니다. 그러나 보안 규칙과 데이터 모델은 다르기 때문에 데이터를 Cloud Firestore로 이동하기 전에 이러한 차이를 신중하게 고려해야 합니다.
이전 데이터를 이동합니다. Cloud Firestore에서 새 데이터 구조를 설정할 때 Realtime Database의 기존 데이터를 새 Cloud Firestore 인스턴스로 매핑하고 이동할 수 있습니다. 하지만 앱에서 두 데이터베이스를 모두 사용하는 경우에는 Realtime Database에서 이전 데이터를 이동할 필요가 없습니다.
새로운 데이터를 실시간으로 Firestore에 미러링합니다. Cloud Functions를 사용하면 Realtime Database에 추가되는 새 데이터를 새 Cloud Firestore 데이터베이스에 쓸 수 있습니다.
Cloud Firestore를 마이그레이션된 데이터의 기본 데이터베이스로 설정합니다. 일부 데이터를 마이그레이션한 후에는 Cloud Firestore를 기본 데이터베이스로 사용하고 마이그레이션된 데이터에 대한 Realtime Database 사용을 줄입니다. 해당 데이터와 관련해 Realtime Database에 연결된 앱 버전과 지속적인 지원 방안을 고려해야 합니다.
Realtime Database 및 Cloud Firestore 모두에 대한 청구 비용을 부담해야 한다는 점에 유의하세요.
데이터 매핑
Realtime Database의 데이터는 단일 트리로 구성되며 Cloud Firestore는 문서, 컬렉션, 하위 컬렉션을 통해 더욱 명확한 데이터 계층 구조를 지원합니다. Realtime Database에서 Cloud Firestore로 일부 데이터를 이동할 때 데이터의 아키텍처 변경을 고려할 수 있습니다.
고려해야 할 주요 차이점
기존 Realtime Database 트리에서 Cloud Firestore 문서 및 컬렉션으로 데이터를 이동할 때 데이터베이스 간의 주요 차이점이 Cloud Firestore에서 데이터를 구조화하는 방법에 영향을 줄 수 있다는 사실에 주의하세요.
- 얕은 쿼리는 계층적 데이터 구조에 더 많은 유연성을 제공합니다.
- 복잡한 쿼리는 더 세분화된 기능을 제공하고 중복 데이터의 필요성을 줄여줍니다.
- 쿼리 커서는 더욱 강력한 페이지화 성능을 제공합니다.
- 트랜잭션 시 모든 데이터에 대해 공통 루트를 사용할 필요가 없어 더 효율적입니다.
- Realtime Database~Cloud Firestore의 청구 비용이 다릅니다. 특히 소규모 작업이 많을 때 Cloud Firestore에 소요되는 비용이 Realtime Database보다 높은 경우가 많습니다. 데이터베이스 작업 횟수를 줄이고 불필요한 쓰기를 피하세요. Realtime Database와 Cloud Firestore의 결제 차이에 대해 자세히 알아보세요.
실행 권장사항
다음 예에는 데이터베이스 간에 데이터를 이동할 때 고려할 수 있는 몇 가지 사항이 나와 있습니다. Realtime Database에서 사용했던 것보다 자연스러운 데이터 구조에 얕은 읽기와 향상된 쿼리 기능을 활용할 수 있습니다.
사용자가 전 세계 도시의 주목할 만한 명소를 쉽게 찾을 수 있도록 도와주는 도시 가이드 앱을 예로 들어 보겠습니다. Realtime Database에는 얕은 읽기가 없기 때문에 다음과 같이 최상위 노드 2개의 데이터를 구조화해야 할 수 있습니다.
// /cities/$CITY_KEY
{
name: "New York",
population: 8000000,
capital: False
}
// /city-landmark/$CITY_KEY/$LANDMARK_KEY
{
name: "Empire State Building",
category: "Architecture"
}
Cloud Firestore는 얕은 읽기를 수행하므로 컬렉션의 문서를 쿼리해도 하위 컬렉션의 데이터를 가져오지 않습니다. 따라서 하위 컬렉션에 랜드마크 정보를 저장할 수 있습니다.
// /cities/$CITY_ID
{
name: "New York",
population: 8000000,
capital: False,
landmarks: [... subcollection ...]
}
문서의 최대 크기는 1MB이기 때문에 중첩된 목록으로 문서의 크기를 늘리기 보다는 각 도시 문서의 용량을 작게 유지하면서 하위 컬렉션으로 랜드마크를 저장해야 합니다.
Cloud Firestore의 고급 쿼리 기능은 공통 액세스 패턴을 위해 데이터를 복제해야 하는 필요를 줄여줍니다. 모든 수도를 인구 통계 순으로 나열하여 보여주는 도시 가이드 앱의 화면을 예로 들어보겠습니다.
Realtime Database에서 이 작업을 수행하는 가장 효율적인 방법은 cities
목록의 데이터를 복제하는 수도 목록을 다음과 같이 별도로 유지하는 것입니다.
{
cities: {
// ...
},
capital-cities: {
// ...
}
}
Cloud Firestore에서는 인구 통계 순의 수도 목록을 다음과 같은 단일 쿼리로 표현할 수 있습니다.
db.collection('cities')
.where('capital', '==', true)
.orderBy('population')
Cloud Firestore 데이터 모델에 관해 자세히 알아보고 Google의 솔루션을 참조하여 Cloud Firestore 데이터베이스를 구성하는 방법에 대해 알아보세요.
데이터 보안
Android, Apple 또는 웹 클라이언트용 Cloud Firestore Security Rules와 서버용 Identity Access Management(IAM) 중 무엇을 사용하든 관계없이 Realtime Database는 물론 Cloud Firestore의 데이터 보안도 철저히 유지해야 합니다. 2개 데이터베이스 모두 사용자 인증이 데이터베이스 인증에 의해 처리되므로 Cloud Firestore 사용을 시작할 때 인증 구현을 변경할 필요가 없습니다.
고려해야 할 주요 차이점
- 모바일 및 웹 SDK는 Cloud Firestore Security Rules를 사용하는 반면 서버 SDK는 Identity Access Management(IAM)를 사용하여 데이터를 보호합니다.
- 와일드 카드를 사용하지 않는 한 Cloud Firestore Security Rules가 하위로 전파되지 않습니다. 문서와 컬렉션은 규칙을 상속받지 않습니다.
- Realtime Database에서와 같이 데이터를 별도로 검증하지 않아도 됩니다.
- Cloud Firestore는 쿼리를 실행하기 전에 사용자가 쿼리에서 반환되는 모든 데이터에 액세스할 수 있는지 규칙을 확인합니다.
이전 데이터를 Cloud Firestore로 이동
데이터 및 보안 구조를 Cloud Firestore의 데이터 및 보안 모델에 매핑하면 데이터 추가를 시작할 수 있습니다. Realtime Database에서 Cloud Firestore로 앱을 이동한 후에 이전 데이터를 쿼리하려면 이전 데이터의 내보내기를 새로운 Cloud Firestore 데이터베이스에 추가하세요. 앱에서 Realtime Database와 Cloud Firestore를 둘 다 사용하려면 이 단계를 건너뛰면 됩니다.
새로운 데이터를 이전 데이터로 덮어쓰지 않으려면 이전 데이터를 먼저 추가해야 할 수 있습니다. 다음 단계의 설명처럼 새로운 데이터를 두 데이터베이스에 동시에 추가하는 경우에는 Cloud Functions를 사용해 Cloud Firestore에 추가된 새로운 데이터에 우선 순위를 부여하세요.
이전 데이터를 Cloud Firestore로 마이그레이션하려면 다음 단계를 따르세요.
- Realtime Database에서 데이터를 내보내거나 최근 백업을 사용합니다.
- Firebase 콘솔에서 Realtime Database 섹션으로 이동합니다.
- 데이터 탭에서 데이터베이스의 루트 레벨 노드를 선택하고 메뉴에서 JSON 내보내기를 선택합니다.
Cloud Firestore에서 새 데이터베이스를 만들고 데이터를 추가합니다.
일부 데이터를 Cloud Firestore로 이동할 때 다음과 같은 전략을 고려해 보세요.
- 데이터를 포트하는 맞춤 스크립트를 작성합니다. 데이터베이스마다 요구사항이 모두 다르므로 스크립트의 템플릿을 제공할 수는 없지만 Slack 채널 또는 Stack Overflow의 Cloud Firestore 전문가들이 스크립트를 검토하거나 특정 상황에 대한 조언을 제공할 수 있습니다.
- 서버 SDK(Node.js, Java, Python 또는 Go)를 사용하여 Cloud Firestore에 직접 데이터를 씁니다. 서버 SDK 설정에 관한 안내는 시작하기를 참조하세요.
- 대규모 데이터 이전을 신속하게 처리하려면 일괄 쓰기를 사용하고 단일 네트워크 요청으로 최대 500개의 작업을 전송합니다.
- Cloud Firestore 비율 제한을 지키려면 각 컬렉션의 초당 쓰기 작업을 500회로 제한합니다.
Cloud Firestore에 새 데이터 추가
데이터베이스를 일치시키려면 두 데이터베이스 모두에 새로운 데이터를 실시간으로 추가해야 합니다. 클라이언트가 Realtime Database에 쓸 때마다 Cloud Functions를 사용하여 Cloud Firestore에 대한 쓰기를 트리거합니다. Cloud Firestore가 이전 데이터 마이그레이션에서 작성된 모든 쓰기보다 Cloud Functions에서 들오는 새로운 데이터를 우선시하도록 지정하세요.
클라이언트가 Realtime Database에 데이터를 쓸 때마다 Cloud Firestore에 신규 또는 변경 데이터를 쓰는 함수를 작성합니다. Cloud Functions의 Realtime Database 트리거에 대해 자세히 알아보세요.
Cloud Firestore를 마이그레이션된 데이터의 기본 데이터베이스로 설정
Cloud Firestore를 일부 데이터의 기본 데이터베이스로 사용하기로 결정했다면 설정한 모든 데이터 미러링 함수를 고려하고 Cloud Firestore Security Rules를 검증합니다.
Cloud Functions를 사용하여 데이터베이스를 일치시키려는 경우 루프 내에서 두 데이터베이스의 쓰기 작업이 중복되지 않도록 주의합니다. 단일 데이터베이스에 쓰도록 함수를 전환하거나, 함수를 완전히 삭제하고 아직 Realtime Database에 연결된 앱의 마이그레이션된 데이터에 대한 쓰기 기능을 단계적으로 종료할 수도 있습니다. 앱에서 이 문제를 처리하는 방법은 구체적인 요구사항과 사용자에 따라 다릅니다.
데이터가 올바르게 보호되는지 확인합니다. Cloud Firestore Security Rules 또는 IAM 설정을 검증합니다.