Cloud Firestore を使ってみる

このクイックスタートでは、Cloud Firestore を設定してデータを追加し、Core オペレーションまたは Pipeline オペレーションを使用して、Firebase コンソールで追加したデータをクエリする方法について説明します。

Cloud Firestore データベースを作成する

  1. まだ Firebase プロジェクトを作成していない場合は作成します。Firebase コンソールで[プロジェクトを追加] をクリックし、画面上の指示に沿って、Firebase プロジェクトを作成するか、Google Cloud プロジェクトに Firebase サービスを追加します。
  1. Firebase コンソールでプロジェクトを開きます。左側のパネルで [ビルド] を展開し、[Firestore データベース] を選択します。

  2. [データベースを作成] をクリックします。

  3. データベース モードとして [Enterprise] を選択します。

  4. オペレーション モードとして [ネイティブ モードの Firestore] を選択します。このモードでは、Core オペレーションと Pipeline オペレーションがサポートされます。

  5. データベースのロケーションを選択します。

  6. Cloud Firestore Security Rules の開始モードを選択します。

    テストモード

    モバイルおよびウェブ クライアント ライブラリを使用する場合に適していますが、すべてのユーザーがデータを読み書きできます。テストが終わったら、必ずデータのセキュリティ保護セクションを確認してください。

    ウェブ、Apple プラットフォーム、Android SDK を使用する場合は、テストモードを選択します。

    本番環境モード

    モバイルおよびウェブ クライアントからのすべての読み書きを拒否します。認証されたアプリケーション サーバー(Python)は引き続きデータベースにアクセスできます。

    デフォルトの Cloud Firestore データベースには、Cloud Firestore Security Rules の初期セットが適用されます。プロジェクトに複数のデータベースを作成する場合は、データベースごとに Cloud Firestore Security Rules をデプロイできます。

  7. [作成] をクリックします。

Cloud Firestore を有効にすると、Cloud API Manager で API も有効になります。

開発環境を設定する

必要な依存関係とクライアント ライブラリをアプリに追加します。

Web

  1. Firebase をウェブアプリに追加するの手順に沿って操作します。
  2. 限定公開プレビュー用の Cloud Firestore SDK は、npm パッケージとして提供されています。

    次のコマンドを使用して、npm プロジェクトに Firestore SDK をインストールします。

    npm install --save firebase@eap-firestore-pipelines
iOS+
  1. Firebase を iOS アプリに追加する手順に従います。
  2. 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
  3. 次に、ディレクトリ(firebase-ios-sdk)をローカル依存関係として Xcode プロジェクトに追加します。
    1. [ファイル] メニューから [パッケージ依存関係を追加] を選択します。
    2. [ローカルを追加…] ボタンをクリックし、チェックアウトした機能ブランチを含む firebase-ios-sdk ディレクトリを探します。
Android
  1. Android アプリに Firebase を追加するの手順に沿って操作します。
  2. 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
  3. プロジェクト レベルの settings.gradle.ktsmavenLocal を追加します。
    dependencyResolutionManagement {
      repositories {
        mavenLocal() // Add this line
        ..
      }
    }
  4. 次に、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
  1. 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
  2. ローカルの python-firestore サーバー SDK をインストールします。
    python -m pip install -e .
  3. 通常どおり 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()

Core オペレーションを使用してデータを追加する

データのクエリに使用する Core オペレーションと Pipeline オペレーションを試すには、Core オペレーションを使用してデータベースにデータを追加します。

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
注: このプロダクトは、watchOS と App Clip の各ターゲットでは利用できません。
// 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
doc_ref = db.collection("users").document("alovelace")
doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815})

次に、別のドキュメントを users コレクションに追加します。このドキュメントには、最初のドキュメントに表示されない Key-Value ペア(ミドルネーム)が含まれています。コレクション内のドキュメントには、それぞれ異なる情報のセットを含めることができます。

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
注: このプロダクトは、watchOS と App Clip の各ターゲットでは利用できません。
// 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
doc_ref = db.collection("users").document("aturing")
doc_ref.set({"first": "Alan", "middle": "Mathison", "last": "Turing", "born": 1912})

Core オペレーションを使用してデータを読み取る

Firebase コンソールのデータビューアを使用して、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
注: このプロダクトは、watchOS と App Clip の各ターゲットでは利用できません。
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()}")

Pipeline オペレーションを使用してデータを読み取る

これで、Pipeline クエリ エクスペリエンスと Core クエリ エクスペリエンスを比較できます。

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 AuthenticationCloud Firestore Security Rules を使用して、Cloud Firestore のデータを保護します。

最初に使用できる基本的なルールセットを以下に示します。セキュリティ ルールはコンソールの [ルール] タブで変更できます。

認証必須

// 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 データにアクセスできるように準備します。App Check のドキュメントをご覧ください。

いずれかのサーバー SDK を使用している場合は、Identity and Access Management(IAM)を使用して Cloud Firestore のデータを保護します。

次のステップ

次のトピックで Core オペレーションと Pipeline オペレーションの知識を深めてください。