使用 Web 客户端库或移动客户端库创建 Firestore 数据库

本快速入门介绍如何使用 Android、Apple 平台、Web、Unity 或 C++ 客户端库设置 Firestore、添加数据和读取数据。

创建 Firestore 数据库

  1. 如果您还没有 Firebase 项目,请创建一个:在 Firebase 控制台中,点击添加项目,然后按照屏幕上的说明创建 Firebase 项目或将 Firebase 服务添加到现有 GCP 项目。

  2. 在 Firebase 控制台的导航窗格中,选择 Firestore,然后点击 Firestore 的创建数据库

  3. 为 Firestore 安全规则选择测试模式

    测试模式
    此模式适合刚开始使用移动和 Web 客户端库的用户,但会允许任何人读取和覆盖您的数据。测试完成后,请务必查看保护您的数据部分。
  4. 选择数据库的位置

    • 此位置设置是您项目的默认 Google Cloud Platform (GCP) 资源位置。请注意,此位置将用于项目中需要位置设置的 GCP 服务,具体来说就是您的默认 Cloud Storage 存储桶和 App Engine 应用(如果您使用 Cloud Scheduler,就需要该应用)。

    • 如果您无法选择位置,表明您的项目已经具有默认 GCP 资源位置。它可能是在项目创建期间设置的,也可能是在设置需要位置设置的其他服务时指定的。

  5. 点击完成

启用 Firestore 时,也会在 Cloud API 管理器中启用相应 API。

设置开发环境

将所需的依赖项和客户端库添加到您的应用。

Web 版本 9

  1. 按照相关说明将 Firebase 添加到您的 Web 应用
  2. 导入 Firebase 和 Firestore:
    import { initializeApp } from "firebase/app";
    import { getFirestore } from "firebase/firestore";
    

Web 版本 8

  1. 按照相关说明将 Firebase 添加到您的 Web 应用
  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
    
    您需要手动通过 require() 函数同时引入 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(Swift 软件包)> 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:24.11.0")

    如果您的应用使用多个 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 build 的大小。
  3. 您必须缩减 build 的大小以避免出现消息 Error while merging dex archives

    • 您可以在 Player Settings > Android > Publishing Settings > Minify 中找到该选项。
    • 具体选项可能会因 Unity 版本而异,因此请参阅官方 Unity 文档Firebase Unity Build 调试指南
    • 如果在启用 Minification 后引用的方法数量仍超过此限制,则另一个选项是在以下位置启用 multidex
      • 如果启用了 Player Settings(玩家设置)下的 Custom Gradle Template(自定义 Gradle 模板),则为 mainTemplate.gradle
      • 模块级 build.gradle 文件(如果您使用 Android Studio 构建导出的项目)。

初始化 Firestore

初始化 Firestore 的实例:

Web 版本 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();
您可以在 Web 应用的“firebaseConfig”中找到“initializeApp”的值。 如需在设备的网络连接中断时保留数据,请参阅启用离线数据文档。

Web 版本 8

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

var db = firebase.firestore();
您可以在 Web 应用的“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+KTX
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 就会隐式创建集合和文档。您不需要显式创建集合或文档。

使用以下示例代码创建一个新集合和一个新文档。

Web 版本 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);
}

Web 版本 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+KTX
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 集合中。请注意,此文档包含第一个文档中没有的一个键值对(中间名)。集合中的文档可以包含不同的信息集。

Web 版本 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);
}

Web 版本 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+KTX
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 方法来检索整个集合。

Web 版本 9

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

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

Web 版本 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+KTX
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 身份验证Firestore 安全规则保护 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 应用部署到生产环境之前,请采取措施确保只有应用客户端才能访问您的 Firestore 数据。请参阅 App Check 文档。

观看视频教程

如果需要开始使用 Firestore 移动和 Web 客户端库的详细指南,请观看以下视频教程之一:

Web
iOS
Android

您可以在 Firebase YouTube 频道中找到更多视频。

后续步骤

通过以下各主题深入了解相关知识: