Get started with Cloud Firestore

This quickstart shows you how to set up Cloud Firestore, add data, then use either Core operations or Pipeline operations to query the data you just added in the Firebase console.

Create a Cloud Firestore database

  1. If you haven't already, create a Firebase project: In the Firebase console, click Add project, then follow the on-screen instructions to create a Firebase project or to add Firebase services to an existing Google Cloud project.
  1. Open your project in the Firebase console. In the left panel, expand Build and then select Firestore database.

  2. Click Create database.

  3. Select Enterprise for the database mode.

  4. Select Firestore in Native Mode for the operation mode, which supports Core and Pipeline operations.

  5. Select a location for your database.

  6. Select a starting mode for your Cloud Firestore Security Rules:

    Test mode

    Good for getting started with the mobile and web client libraries, but allows anyone to read and overwrite your data. After testing, make sure to review the Secure your data section.

    To get started with the web, Apple platforms, or Android SDK, select test mode.

    Production mode

    Denies all reads and writes from mobile and web clients. Your authenticated application servers (Python) can still access your database.

    Your initial set of Cloud Firestore Security Rules will apply to your default Cloud Firestore database. If you create multiple databases for your project, you can deploy Cloud Firestore Security Rules for each database.

  7. Click Create.

When you enable Cloud Firestore, it also enables the API in the Cloud API Manager.

Set up your development environment

Add the required dependencies and client libraries to your app.

Web

  1. Follow the instructions to add Firebase to your web app.
  2. The Cloud Firestore SDK for Private Preview is available as an npm package.

    Use the following command to install the Firestore SDK in your npm project.

    npm install --save firebase@eap-firestore-pipelines
iOS+
  1. Follow the instructions to add Firebase to your iOS app.
  2. Clone the Firebase SDK from GitHub and check out the pipelines branch. Make a note of the location you clone it to, since you'll need it in the next step:
    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. Then add the directory (firebase-ios-sdk) as a local dependency to your Xcode project:
    1. From the File menu, choose Add Package Dependencies.
    2. Click the Add Local… button, then locate the firebase-ios-sdk directory with the feature branch you've checked out.
Android
  1. Follow the instructions to add Firebase to your Android app.
  2. Clone the Firebase SDK from GitHub, check out the pipelines branch, and publish it to local 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. Add mavenLocal to the project level settings.gradle.kts:
    dependencyResolutionManagement {
      repositories {
        mavenLocal() // Add this line
        ..
      }
    }
  4. Then, add the local version of the 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. Clone the Firestore Python SDK and check out the pipeline preview branch:
    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. Install the local python-firestore server SDK:
    python -m pip install -e .
  3. Install the Firebase Python Admin SDK as usual:
    pip install --user firebase-admin

Initialize Cloud Firestore

Initialize an instance of 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');

Replace FIREBASE_CONFIGURATION with your web app's firebaseConfig.

To persist data when the device loses its connection, see the Enable Offline Data documentation.

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

Authenticate with your enterprise database using 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()

Add data using Core operations

In order to explore Core operations and Pipeline operations for querying data, add data to your database using Core operations.

Cloud Firestore stores data in Documents, which are stored in Collections. Cloud Firestore creates collections and documents implicitly the first time you add data to the document. You don't need to explicitly create collections or documents.

Create a new collection and a document using the following example code.

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
Note: This product is not available on watchOS and App Clip targets.
// 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})

Now add another document to the users collection. Notice that this document includes a key-value pair (middle name) that does not appear in the first document. Documents in a collection can contain different sets of information.

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
Note: This product is not available on watchOS and App Clip targets.
// 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})

Read data using Core operations

Use the data viewer in the Firebase console to quickly verify that you've added data to Cloud Firestore.

You can also use the "get" method to retrieve the entire collection.

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
Note: This product is not available on watchOS and App Clip targets.
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()}")

Read data using Pipeline operations

Now you can compare the Pipeline query experience with the Core query experience.

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

Secure your data

If you're using the web, Android, or Apple platforms SDK, use Firebase Authentication and Cloud Firestore Security Rules to secure your data in Cloud Firestore.

Here are some basic rule sets you can use to get started. You can modify your security rules in the Rules tab of the console.

Auth required

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

Production mode

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

Before you deploy your web, Android, or iOS app to production, also take steps to ensure that only your app clients can access your Cloud Firestore data. See the App Check documentation.

If you're using one of the server SDKs, use Identity and Access Management (IAM) to secure your data in Cloud Firestore.

Next steps

Deepen your knowledge of Core and Pipeline operations with the following topics: