開始使用 Cloud Firestore

本快速入門導覽課程說明如何設定 Cloud Firestore、新增資料,然後使用核心作業或管道作業,查詢您剛在 Firebase 控制台中新增的資料。

建立 Cloud Firestore 資料庫

  1. 如果尚未建立 Firebase 專案,請在 Firebase 控制台中按一下「新增專案」,然後按照畫面上的指示建立 Firebase 專案,或將 Firebase 服務新增至現有的 Google Cloud 專案。
  1. Firebase 控制台中開啟專案。在左側面板中展開「建構」,然後選取「Firestore 資料庫」

  2. 按一下 [Create database] (建立資料庫)。

  3. 選取「Enterprise」做為資料庫模式。

  4. 選取「原生模式的 Firestore」做為作業模式,支援核心和管道作業。

  5. 選取資料庫的位置

  6. 選取 Cloud Firestore Security Rules 的起始模式:

    測試模式

    適合用來開始使用行動和網路用戶端程式庫,但允許任何人讀取及覆寫您的資料。測試完成後,請務必查看「保護資料」一節。

    如要開始使用網頁、Apple 平台或 Android SDK,請選取測試模式。

    正式版模式

    拒絕行動和網路用戶端的所有讀寫要求。 通過驗證的應用程式伺服器 (Python) 仍可存取資料庫。

    初始設定的 Cloud Firestore Security Rules 會套用至預設Cloud Firestore資料庫。如果為專案建立多個資料庫,可以為每個資料庫部署 Cloud Firestore Security Rules

  7. 點選「建立」

啟用 Cloud Firestore 時,系統也會在 Cloud API 管理工具中啟用 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. 從「File」選單中選擇「Add Package Dependencies」
    2. 按一下「Add Local…」按鈕,然後找出 firebase-ios-sdk 目錄,其中包含您已簽出的功能分支。
Android
  1. 按照操作說明將 Firebase 新增至 Android 應用程式
  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.kts 中加入 mavenLocal
    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 作業和管道作業,請使用 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 集合。請注意,這份文件包含第一個文件中沒有的鍵/值組合 (中間名)。集合中的文件可以包含不同的資訊集。

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})

使用核心作業讀取資料

使用 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 查詢體驗與 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,請使用身分與存取權管理 (IAM),確保 Cloud Firestore 中的資料安全無虞。

後續步驟

透過下列主題深入瞭解 Core 和管道作業: