使用網頁/行動用戶端程式庫建立 Firestore 資料庫

本快速入門指南將說明如何使用 Android、Apple 平台、Web、Unity 或 C++ 用戶端程式庫,設定 Firestore、新增資料及讀取資料。

  1. 如果尚未建立 Firebase 專案,請先建立:在 Firebase 控制台中,按一下「新增專案」,然後按照畫面上的指示建立 Firebase 專案,或將 Firebase 服務新增至現有的 Google Cloud 專案。

  2. 在 Firebase 控制台中開啟專案。在左側面板中展開「Build」,然後選取「Firestore database」

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

  4. 選取資料庫的位置

    如果無法選取位置,表示專案的「預設資源位置」 Google Cloud 已設定完畢。專案的部分資源 (例如預設 Firestore 執行個體) 共用常見的位置依附元件,您可以在建立專案時或設定共用此位置依附元件的其他服務時,設定這些資源的位置。

  5. 選取 Firestore 安全性規則的起始模式:

    測試模式

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

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

    鎖定模式

    拒絕行動和網路用戶端的所有讀寫要求。 通過驗證的應用程式伺服器 (C#、Go、Java、Node.js、PHP、Python 或 Ruby) 仍可存取資料庫。

    如要開始使用 C#、Go、Java、Node.js、PHP、Python 或 Ruby 伺服器用戶端程式庫,請選取鎖定模式。

    初始的 Firestore 安全性規則集會套用至預設的 Firestore 資料庫。如果為專案建立多個資料庫,可以為每個資料庫部署 Firestore 安全性規則。

  6. 點選「建立」

啟用 Firestore 時,系統也會在 Cloud API 管理工具中啟用 API。

設定開發環境

將必要的依附元件和用戶端程式庫新增至應用程式。

網頁版 9

  1. 按照操作說明將 Firebase 新增至您的網頁應用程式
  2. 匯入 Firebase 和 Firestore:
    import { initializeApp } from "firebase/app";
    import { getFirestore } from "firebase/firestore";

網頁版 8

  1. 按照操作說明將 Firebase 新增至您的網頁應用程式
  2. 將 Firebase 和 Firestore 程式庫新增至應用程式:
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-firestore.js"></script>
    Firestore SDK 也提供 npm 套件。
    npm install firebase@8.10.1 --save
    您需要手動要求 Firebase 和 Firestore。
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/firestore");
Apple 平台

按照操作說明將 Firebase 新增至 Apple 應用程式

使用 Swift Package Manager 安裝及管理 Firebase 依附元件。

  1. 在 Xcode 中保持開啟應用程式專案,然後依序點選「File」>「Swift Packages」>「Add Package Dependency」
  2. 系統提示時,請新增 Firebase Apple 平台 SDK 存放區:
  3.   https://github.com/firebase/firebase-ios-sdk
      
  4. 選擇 Firestore 程式庫。
  5. 完成後,Xcode 會自動開始在背景中解析並下載依附元件。
Android
  1. 按照操作說明將 Firebase 新增至 Android 應用程式
  2. 在模組 (應用程式層級) Gradle 檔案 (通常為 app/build.gradle.ktsapp/build.gradle) 中,宣告 Android 適用的 Firestore 程式庫依附元件:
    implementation("com.google.firebase:firebase-firestore:25.1.4")

    如果應用程式使用多個 Firebase 程式庫,建議使用 Firebase Android BoM,確保應用程式的 Firebase 程式庫版本一律相容。

    想尋找 Kotlin 專屬的程式庫模組嗎?2023 年 10 月發布版本起,Kotlin 和 Java 開發人員都可以依附於主要程式庫模組 (詳情請參閱這項計畫的常見問題)。

Dart

  1. 如果尚未完成,請在 Flutter 應用程式中設定及初始化 Firebase
  2. 在 Flutter 專案的根目錄中,執行下列指令來安裝外掛程式:
    flutter pub add cloud_firestore
  3. 完成後,請重建 Flutter 應用程式:
    flutter run
C++
  1. 按照操作說明將 Firebase 新增至 C++ 專案
  2. Android 的 C++ 介面。
    • Gradle 依附元件。將以下內容加入模組 (應用程式層級) Gradle 檔案 (通常為 app/build.gradle):
              android.defaultConfig.externalNativeBuild.cmake {
                arguments "-DFIREBASE_CPP_SDK_DIR=$gradle.firebase_cpp_sdk_dir"
              }
      
              apply from: "$gradle.firebase_cpp_sdk_dir/Android/firebase_dependencies.gradle"
              firebaseCpp.dependencies {
                // earlier entries
                auth
                firestore
              }
              
    • 二進位檔依附元件。同樣地,建議您在 CMakeLists.txt 檔案中加入下列內容,取得二進位檔依附元件:
              add_subdirectory(${FIREBASE_CPP_SDK_DIR} bin/ EXCLUDE_FROM_ALL)
              set(firebase_libs firebase_auth firebase_firestore firebase_app)
              # Replace the target name below with the actual name of your target,
              # for example, "native-lib".
              target_link_libraries(${YOUR_TARGET_NAME_HERE} "${firebase_libs}")
              
  3. 如要設定桌面整合,請參閱「將 Firebase 新增至您的 C++ 專案」。
Unity
  1. 按照操作說明將 Firebase 新增至您的 Unity 專案
  2. 使用 Unity 介面設定專案,縮減 Android 建構作業。
  3. 您必須縮減建構作業,才能避免收到 Error while merging dex archives 訊息。

    • 這個選項位於「Player Settings」>「Android」>「Publishing Settings」>「Minify」
    • 不同版本的 Unity 可能會提供不同的選項,因此請參閱官方 Unity 說明文件Firebase Unity 建構偵錯指南
    • 如果啟用縮減功能後,參照的方法數量仍超過限制,可以啟用 multidex
      • mainTemplate.gradle 如果已啟用「Player Settings」下的「Custom Gradle Template」
      • 如果您使用 Android Studio 建構匯出的專案,則為模組層級的 build.gradle 檔案。

初始化原生模式的 Firestore

初始化 Firestore 執行個體:

網頁版 9

// Initialize Firestore through Firebase
import { initializeApp } from "firebase/app"
import { getFirestore } from "firebase/firestore"
const firebaseApp = initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###'
});

const db = getFirestore();
您可以在網頁應用程式的 `firebaseConfig` 中找到`initializeApp`的值。 如要在裝置失去連線時保留資料,請參閱「啟用離線資料」文件。

網頁版 8

// Initialize Firestore through Firebase
firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###'
});

var db = firebase.firestore();
您可以在網頁應用程式的 `firebaseConfig` 中找到`initializeApp`的值。 如要在裝置失去連線時保留資料,請參閱「啟用離線資料」文件。
Swift
注意:這項產品不適用於 watchOS 和 App Clip 目標。
import FirebaseCore
import FirebaseFirestore

FirebaseApp.configure()

let db = Firestore.firestore()
Objective-C
注意:這項產品不適用於 watchOS 和 App Clip 目標。
@import FirebaseCore;
@import FirebaseFirestore;

// Use Firebase library to configure APIs
[FIRApp configure];

FIRFirestore *defaultFirestore = [FIRFirestore firestore];
  
Kotlin
Android
  // Access a Firestore instance from your Activity
  val db = Firebase.firestore
Java
Android
// Access a Firestore instance from your Activity
  FirebaseFirestore db = FirebaseFirestore.getInstance();

Dart

db = FirebaseFirestore.instance;
C++
// Make sure the call to `Create()` happens some time before you call Firestore::GetInstance().
App::Create();
Firestore* db = Firestore::GetInstance();
Unity
using Firebase.Firestore;
using Firebase.Extensions;
FirebaseFirestore db = FirebaseFirestore.DefaultInstance;

新增資料

Firestore 會將資料儲存在文件中,並將文件儲存在集合中。 首次將資料新增至文件時,Firestore 會隱含地建立集合和文件。您不必明確建立集合或文件。

使用下列範例程式碼建立新集合和文件。

網頁版 9

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

網頁版 8

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)")
}
Objective-C
注意:這項產品不適用於 watchOS 和 App Clip 目標。
// Add a new document with a generated ID
__block FIRDocumentReference *ref =
    [[self.db collectionWithPath:@"users"] addDocumentWithData:@{
      @"first": @"Ada",
      @"last": @"Lovelace",
      @"born": @1815
    } completion:^(NSError * _Nullable error) {
      if (error != nil) {
        NSLog(@"Error adding document: %@", error);
      } else {
        NSLog(@"Document added with ID: %@", ref.documentID);
      }
    }];
Kotlin
Android
// 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
Android
// 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);
            }
        });

Dart

// Create a new user with a first and last name
final user = <String, dynamic>{
  "first": "Ada",
  "last": "Lovelace",
  "born": 1815
};

// Add a new document with a generated ID
db.collection("users").add(user).then((DocumentReference doc) =>
    print('DocumentSnapshot added with ID: ${doc.id}'));
C++
// Add a new document with a generated ID
Future<DocumentReference> user_ref =
    db->Collection("users").Add({{"first", FieldValue::String("Ada")},
                                 {"last", FieldValue::String("Lovelace")},
                                 {"born", FieldValue::Integer(1815)}});

user_ref.OnCompletion([](const Future<DocumentReference>& future) {
  if (future.error() == Error::kErrorOk) {
    std::cout << "DocumentSnapshot added with ID: " << future.result()->id()
              << std::endl;
  } else {
    std::cout << "Error adding document: " << future.error_message() << std::endl;
  }
});
Unity
DocumentReference docRef = db.Collection("users").Document("alovelace");
Dictionary<string, object> user = new Dictionary<string, object>
{
	{ "First", "Ada" },
	{ "Last", "Lovelace" },
	{ "Born", 1815 },
};
docRef.SetAsync(user).ContinueWithOnMainThread(task => {
	Debug.Log("Added data to the alovelace document in the users collection.");
});

現在將另一份文件新增至 users 集合。請注意,這份文件包含第一個文件中沒有的鍵/值組合 (中間名)。集合中的文件可以包含不同的資訊集。

網頁版 9

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

網頁版 8

// 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)")
}
Objective-C
注意:這項產品不適用於 watchOS 和 App Clip 目標。
// Add a second document with a generated ID.
__block FIRDocumentReference *ref =
    [[self.db collectionWithPath:@"users"] addDocumentWithData:@{
      @"first": @"Alan",
      @"middle": @"Mathison",
      @"last": @"Turing",
      @"born": @1912
    } completion:^(NSError * _Nullable error) {
      if (error != nil) {
        NSLog(@"Error adding document: %@", error);
      } else {
        NSLog(@"Document added with ID: %@", ref.documentID);
      }
    }];
Kotlin
Android
// 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
Android
// 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);
            }
        });

Dart

// Create a new user with a first and last name
final user = <String, dynamic>{
  "first": "Alan",
  "middle": "Mathison",
  "last": "Turing",
  "born": 1912
};

// Add a new document with a generated ID
db.collection("users").add(user).then((DocumentReference doc) =>
    print('DocumentSnapshot added with ID: ${doc.id}'));
C++
db->Collection("users")
    .Add({{"first", FieldValue::String("Alan")},
          {"middle", FieldValue::String("Mathison")},
          {"last", FieldValue::String("Turing")},
          {"born", FieldValue::Integer(1912)}})
    .OnCompletion([](const Future<DocumentReference>& future) {
      if (future.error() == Error::kErrorOk) {
        std::cout << "DocumentSnapshot added with ID: "
                  << future.result()->id() << std::endl;
      } else {
        std::cout << "Error adding document: " << future.error_message()
                  << std::endl;
      }
    });
Unity
DocumentReference docRef = db.Collection("users").Document("aturing");
Dictionary<string, object> user = new Dictionary<string, object>
{
	{ "First", "Alan" },
	{ "Middle", "Mathison" },
	{ "Last", "Turing" },
	{ "Born", 1912 }
};
docRef.SetAsync(user).ContinueWithOnMainThread(task => {
	Debug.Log("Added data to the aturing document in the users collection.");
});

讀取資料

使用 Firebase 控制台中的資料檢視器,快速確認您已將資料新增至 Firestore。

您也可以使用 get 方法擷取整個集合。

網頁版 9

import { collection, getDocs } from "firebase/firestore"; 

const querySnapshot = await getDocs(collection(db, "users"));
querySnapshot.forEach((doc) => {
  console.log(`${doc.id} => ${doc.data()}`);
});

網頁版 8

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)")
}
Objective-C
注意:這項產品不適用於 watchOS 和 App Clip 目標。
[[self.db collectionWithPath:@"users"]
    getDocumentsWithCompletion:^(FIRQuerySnapshot * _Nullable snapshot,
                                 NSError * _Nullable error) {
      if (error != nil) {
        NSLog(@"Error getting documents: %@", error);
      } else {
        for (FIRDocumentSnapshot *document in snapshot.documents) {
          NSLog(@"%@ => %@", document.documentID, document.data);
        }
      }
    }];
Kotlin
Android
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
Android
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());
                }
            }
        });

Dart

await db.collection("users").get().then((event) {
  for (var doc in event.docs) {
    print("${doc.id} => ${doc.data()}");
  }
});
C++
Future<QuerySnapshot> users = db->Collection("users").Get();
users.OnCompletion([](const Future<QuerySnapshot>& future) {
  if (future.error() == Error::kErrorOk) {
    for (const DocumentSnapshot& document : future.result()->documents()) {
      std::cout << document << std::endl;
    }
  } else {
    std::cout << "Error getting documents: " << future.error_message()
              << std::endl;
  }
});
Unity
CollectionReference usersRef = db.Collection("users");
usersRef.GetSnapshotAsync().ContinueWithOnMainThread(task =>
{
  QuerySnapshot snapshot = task.Result;
  foreach (DocumentSnapshot document in snapshot.Documents)
  {
    Debug.Log(String.Format("User: {0}", document.Id));
    Dictionary<string, object> documentDictionary = document.ToDictionary();
    Debug.Log(String.Format("First: {0}", documentDictionary["First"]));
    if (documentDictionary.ContainsKey("Middle"))
    {
      Debug.Log(String.Format("Middle: {0}", documentDictionary["Middle"]));
    }

    Debug.Log(String.Format("Last: {0}", documentDictionary["Last"]));
    Debug.Log(String.Format("Born: {0}", documentDictionary["Born"]));
  }

  Debug.Log("Read all data from the users collection.");
});

確保資料安全

使用 Firebase AuthenticationFirestore 安全性規則,保護原生模式 Firestore 中的資料。

以下是一些基本規則集,可供您做為入門參考。您可以在 Firebase 控制台的「規則」分頁中修改安全性規則。

需要驗證

// Allow read/write access on all documents to any user signed in to the application
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

鎖定模式

// Deny read/write access to all users under any conditions
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

測試模式

// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

將 Web、Android 或 iOS 應用程式部署至正式環境前,請採取相關步驟,確保只有應用程式用戶端可以存取 Native 模式的 Firestore 資料。請參閱 App Check 說明文件。

觀看教學影片

如需開始使用 Firestore 行動和網頁用戶端程式庫的詳細指南,請觀看下列其中一個影片教學課程:

網頁
iOS
Android

如要觀看更多影片,請前往 Firebase YouTube 頻道

後續步驟

深入瞭解下列主題:

  • 程式碼實驗室:按照 AndroidiOSWeb 的程式碼實驗室操作,瞭解如何在實際應用程式中使用 Firestore 原生模式。
  • 資料模型:進一步瞭解 Firestore 的資料結構,包括階層式資料和子集合。
  • 新增資料:進一步瞭解如何在 Firestore 中建立及更新資料。
  • 取得資料:進一步瞭解如何擷取資料。
  • 執行簡單和複合查詢:瞭解如何執行簡單和複合查詢。
  • 排序及限制查詢:瞭解如何排序及限制查詢傳回的資料。