Cloud Firestore is a NoSQL, document-oriented database. Unlike a SQL database,
there are no tables or rows. Instead, you store data in
documents
, which are
organized into
collections
.
Each
document
contains a set of key-value pairs. Cloud Firestore is
optimized for storing large collections of small documents.
All documents must be stored in collections. Documents can contain
subcollections
and nested objects, both of which can include primitive fields
like strings or complex objects like lists.
Collections and documents are created implicitly in Cloud Firestore.
Simply assign data to a document within a collection. If either the collection
or document does not exist, Cloud Firestore creates it.
Documents
In Cloud Firestore, the unit of storage is the document. A document is a
lightweight record that contains fields, which map to values. Each document is
identified by a name.
A document representing a user
alovelace
might look like this:
Complex, nested objects in a document are called maps. For example, you could
structure the user's name from the example above with a map, like this:
You may notice that documents look a lot like JSON. In fact, they basically are.
There are some differences (for example, documents support extra data types and
are limited in size to 1 MB), but in general, you can treat documents as
lightweight JSON records.
Collections
Documents live in collections, which are simply containers for documents. For
example, you could have a
users
collection to contain your various users, each
represented by a document:
Cloud Firestore is schemaless, so you have complete freedom over what
fields you put in each document and what data types you store in those fields.
Documents within the same collection can all contain different fields or store
different types of data in those fields. However, it's a good idea to use the
same fields and data types across multiple documents, so that you can query the
documents more easily.
A collection contains documents and nothing else. It can't directly contain raw
fields with values, and it can't contain other collections. (See
Hierarchical
Data
for an explanation of how to structure more complex
data in Cloud Firestore.)
The names of documents within a collection are unique. You can provide your own
keys, such as user IDs, or you can let Cloud Firestore create random IDs
for you automatically.
You do not need to "create" or "delete" collections. After you create the first
document in a collection, the collection exists. If you delete all of the
documents in a collection, it no longer exists.
References
Every document in Cloud Firestore is uniquely identified by its location
within the database. The previous example showed a document
alovelace
within
the collection
users
. To refer to this location in your code, you can create a
reference
to it.
Web modular API
import { doc } from "firebase/firestore";
const alovelaceDocumentRef = doc(db, 'users', 'alovelace');
Web namespaced API
var alovelaceDocumentRef = db.collection('users').doc('alovelace');
Swift
Note:
This product is not available on watchOS and App Clip targets.
let alovelaceDocumentRef = db.collection("users").document("alovelace")
Objective-C
Note:
This product is not available on watchOS and App Clip targets.
FIRDocumentReference *alovelaceDocumentRef =
[[self.db collectionWithPath:@"users"] documentWithPath:@"alovelace"];
Kotlin+KTX
val alovelaceDocumentRef = db.collection("users").document("alovelace")
Java
DocumentReference alovelaceDocumentRef = db.collection("users").document("alovelace");
Dart
final alovelaceDocumentRef = db.collection("users").doc("alovelace");
C++
DocumentReference alovelace_document_reference =
db->Collection("users").Document("alovelace");
Unity
DocumentReference documentRef = db.Collection("users").Document("alovelace");
A reference is a lightweight object that just points to a location in your
database. You can create a reference whether or not data exists there, and
creating a reference does not perform any network operations.
You can also create references to
collections
:
Web modular API
import { collection } from "firebase/firestore";
const usersCollectionRef = collection(db, 'users');
Web namespaced API
var usersCollectionRef = db.collection('users');
Swift
Note:
This product is not available on watchOS and App Clip targets.
let usersCollectionRef = db.collection("users")
Objective-C
Note:
This product is not available on watchOS and App Clip targets.
FIRCollectionReference *usersCollectionRef = [self.db collectionWithPath:@"users"];
Kotlin+KTX
val usersCollectionRef = db.collection("users")
Java
CollectionReference usersCollectionRef = db.collection("users");
Dart
final usersCollectionRef = db.collection("users");
C++
CollectionReference users_collection_reference = db->Collection("users");
Unity
CollectionReference collectionRef = db.Collection("users");
For convenience, you can also create references by specifying the path to a
document or collection as a string, with path components separated by a forward
slash (
/
). For example, to create a reference to the
alovelace
document:
Web modular API
import { doc } from "firebase/firestore";
const alovelaceDocumentRef = doc(db, 'users/alovelace');
Web namespaced API
var alovelaceDocumentRef = db.doc('users/alovelace');
Swift
Note:
This product is not available on watchOS and App Clip targets.
let aLovelaceDocumentReference = db.document("users/alovelace")
Objective-C
Note:
This product is not available on watchOS and App Clip targets.
FIRDocumentReference *aLovelaceDocumentReference =
[self.db documentWithPath:@"users/alovelace"];
Kotlin+KTX
val alovelaceDocumentRef = db.document("users/alovelace")
Java
DocumentReference alovelaceDocumentRef = db.document("users/alovelace");
Dart
final aLovelaceDocRef = db.doc("users/alovelace");
C++
DocumentReference alovelace_document = db->Document("users/alovelace");
Unity
DocumentReference documentRef = db.Document("users/alovelace");
Hierarchical Data
To understand how hierarchical data structures work in Cloud Firestore,
consider an example chat app with messages and chat rooms.
You can create a collection called
rooms
to store different chat rooms:
Now that you have chat rooms, decide how to store your messages. You might not
want to store them in the chat room's document. Documents in Cloud Firestore
should be lightweight, and a chat room could contain a large number of messages.
However, you can create additional collections within your chat room's document,
as subcollections.
Subcollections
The best way to store messages in this scenario is by using subcollections. A
subcollection is a collection associated with a specific document.
You can create a subcollection called
messages
for every room document in
your
rooms
collection:
In this example, you would create a reference to a message in the subcollection
with the following code:
Web modular API
import { doc } from "firebase/firestore";
const messageRef = doc(db, "rooms", "roomA", "messages", "message1");
Web namespaced API
var messageRef = db.collection('rooms').doc('roomA')
.collection('messages').doc('message1');
Swift
Note:
This product is not available on watchOS and App Clip targets.
let messageRef = db
.collection("rooms").document("roomA")
.collection("messages").document("message1")
Objective-C
Note:
This product is not available on watchOS and App Clip targets.
FIRDocumentReference *messageRef =
[[[[self.db collectionWithPath:@"rooms"] documentWithPath:@"roomA"]
collectionWithPath:@"messages"] documentWithPath:@"message1"];
Kotlin+KTX
val messageRef = db
.collection("rooms").document("roomA")
.collection("messages").document("message1")
Java
DocumentReference messageRef = db
.collection("rooms").document("roomA")
.collection("messages").document("message1");
Dart
final messageRef = db
.collection("rooms")
.doc("roomA")
.collection("messages")
.doc("message1");
C++
DocumentReference message_reference = db->Collection("rooms")
.Document("roomA")
.Collection("messages")
.Document("message1");
Unity
DocumentReference documentRef = db
.Collection("Rooms").Document("RoomA")
.Collection("Messages").Document("Message1");
Notice the alternating pattern of collections and documents. Your collections
and documents must always follow this pattern. You cannot reference a collection
in a collection or a document in a document.
Subcollections allow you to structure data hierarchically, making data easier to
access. To get all messages in
roomA
, you can create a collection reference
to the subcollection
messages
and interact with it like you would any other
collection reference.
Documents in subcollections can contain subcollections as well, allowing you to
further nest data. You can nest data up to 100 levels deep.