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

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

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

  2. 在 Firebase 控制台中打开您的项目。在左侧面板中,展开构建,然后选择 Firestore 数据库

  3. 点击创建数据库

  4. 选择数据库的位置

    如果您无法选择位置,则表明项目的“默认 Google Cloud 资源位置”已经设置。您的项目的部分资源(例如默认 Firestore 实例)共享一个通用位置依赖项,并且可以在项目创建期间或设置共享此位置依赖项的其他服务时设置其位置。

  5. 为您的 Firestore 安全规则选择一个初始模式:

    测试模式

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

    如需开始使用 Web、Apple 平台或 Android SDK,请选择测试模式。

    锁定模式

    此模式会拒绝来自移动和 Web 客户端的所有读写操作。经过身份验证的应用服务器(C#、Go、Java、Node.js、PHP、Python 或 Ruby)仍然可以访问您的数据库。

    如需开始使用 C#、Go、Java、Node.js、PHP、Python 或 Ruby 服务器客户端库,请选择锁定模式。

    最初的一组 Firestore 安全规则将应用于您的默认 Firestore 数据库。如果您为项目创建多个数据库,则可以为每个数据库部署 Firestore 安全规则。

  6. 点击创建

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

设置开发环境

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

网站

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

网站

  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)中声明 Firestore Android 库的依赖项:
    implementation("com.google.firebase:firebase-firestore:25.1.3")

    如果您的应用使用多个 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}")
            
  • 如需设置桌面集成,请参阅将 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 调试指南
    • 如果在启用缩减大小后,引用的方法数量仍然超过上限,另一种方法是在以下位置启用 multidex
      • mainTemplate.gradle(如果启用了 Player Settings 下的 Custom Gradle Template
      • 模块级 build.gradle 文件(如果您使用 Android Studio 构建导出的项目)。

    初始化 Firestore

    初始化 Firestore 的实例:

    网站

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

    网站

    // Initialize Firestore through Firebase
    firebase.initializeApp({
      apiKey: '### FIREBASE API KEY ###',
      authDomain: '### FIREBASE AUTH DOMAIN ###',
      projectId: '### CLOUD FIRESTORE PROJECT ID ###'
    });
    
    var db = firebase.firestore();
    “initializeApp”的值可以在您 Web 应用的 “firebaseConfig” 中找到。如需在设备的网络连接中断时保留数据,请参阅启用离线数据文档。
    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 就会隐式创建集合和文档。您不需要显式创建集合或文档。

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

    网站

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

    网站

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

    网站

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

    网站

    // 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 方法来检索整个集合。

    网站

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

    网站

    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 身份验证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 频道中找到更多视频。

    后续步骤

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