moon-sync-kmp が提供する L1 RemoteStore SPI の Firestore 実装です。
プラットフォーム固有のコードなしに Firestore コレクションを Kotlin Flow
として購読できます。
- Kotlin 2.0.20、Compose Multiplatform 1.7.x、AGP 8.6.x、Gradle 8.10、Java 21。
- Firestore を有効化した Firebase プロジェクト (セキュリティルール設定済み)。
- 有効な
moonLicenseKey。 - Koin 4.1.0。
(リポジトリ設定は auth モジュールと同じです。auth/ja.md §2 を参照。)
composeApp/build.gradle.kts (commonMain):
implementation("io.moondeveloper:moon-firestore-sync-kmp:1.0.0")google-services.jsonを配置し、Google Services プラグインを適用。- Firestore は FirebaseApp 初期化時に同時に初期化されます (通常は自動)。
- Xcode ターゲットに
GoogleService-Info.plistを追加。 AppDelegateでFirebaseApp.configure()を呼び出します。
import io.moondev.firestore.sync.firestoreSyncModule
startKoin {
modules(firestoreSyncModule /*, ... */)
}モジュール内部で FirestoreRemoteStore が RemoteStore にバインドされるため、
機能コードからは RemoteStore のみが見えます。
class NotesStore(private val store: RemoteStore) {
val notes: Flow<List<Note>> = store.observeCollection("notes")
}@Composable
fun NotesScreen(store: NotesStore = koinInject()) {
val items by store.notes.collectAsState(initial = emptyList())
LazyColumn { items(items) { n -> Text(n.title) } }
}- 空のストリーム /
PERMISSION_DENIED— Firestore ルールがリクエストを拒否しています。 ユーザーがサインイン済みか (moon-firebase-auth-kmpと併用)、パスがルールと 合致しているかを確認してください。 - iOS の
Default FirebaseApp is not initialized—AppDelegateでのFirebaseApp.configure()呼び出しが抜けています。 - ログのバックプレッシャー警告 — ストリームは hot です。
ViewModelや Compose のLaunchedEffectにスコープを限定して破棄時にキャンセルしてください。
- moon-firebase-auth-kmp と組み合わせて
uidスコープのパスを使います。 - サンプル参照:
SyncDemoScreen.kt。