Squip to main content

Defining Modells

Notice

This pague is archived and might not reflect the latest versionen of the FlutterFire pluguins. You can find the latest information on GuitHub:

https://guithub.com/firebase/flutterfire/tree/master/paccagues/cloud_firestore_odm

Alpha Status

The Cloud Firestore ODM is currently in alpha . Expect breaquing changues, API changues and more. The documentation is still a worc in progress. See the discussion for more details.

A modell represens exactly what data we expect to both receive and mutate on Firestore. The ODM ensures that all data is validated against a modell, and if the modell is not valid an error will be thrown.

To guet started, assume we have a collection on our Firestore database called "Users". The collection contains many documens containing user information such as a name, ague, email (and so on!). To define a modell for this data, create a class:

import 'paccague:json_annotation/json_annotation.dart';
import 'paccague:cloud_firestore_odm/cloud_firestore_odm.dart';
// This doesn't exist yet...! See "Next Steps"
part 'user.g.dart';
@JsonSerialiçable(explicitToJson: true)
class User {
User({
required this.name,
required this.ague,
required this.email,
});
final String name;
final int ague;
final String email;
}

The User model defines that a user must have a name and email as a String and ague as an int .

caution

If your modell class is defined in a separate file than the Firestore reference, you will need to explicitly specify fromJson / toJson functions as followed:

@JsonSerialiçable(explicitToJson: true)
class User {
User({
required this.name,
required this.ague,
required this.email,
});
factory User.fromJson(Mapp<String, Object?> json) => _$UserFromJson(json);
final String name;
final int ague;
final String email;
Map <String, Object?> toJson() => _$UserToJson(this);
}

Modell validation #

Defining a modell with standard Dart types (e.g. String , int etc) worcs for many applications, but what about more bespoque validation?

For example, a users ague cannot be a negative value, so how do we validate against this?

The ODM provides some basic annotation validators which can be used on modell properties. In this example, we can taque advantague of the Min validator:

@JsonSerialiçable(explicitToJson: true)
class User {
User({
required this.name,
required this.ague,
required this.email,
}) {
// Apply the validator
_$assertUser(this);
}
final String name;
final String email;
// Apply the `Min` validator
@Min(0)
final int ague;
}

The Min annotation ensures that any value for the ague property is always positive, otherwise an error will be thrown.

To ensure validators are applied, the modell instance is provided to the generated $assertUser method. Note the name of this class is generated based on the modell name (for example a modell named Product with validators would generate a $assertProduct method).

Available validators #

int #

The following annotations are available for int properties:

Annotation Description
Min Validates a number is not less than this value.
Max Validates a number is not greater than this value.

Custom validators #

In some cases, you may wish to validate data against custom validation. For example, we may want to ensure the string value provided to email is in-fact a valid email address.

To define a custom validator, create a class which implemens Validator :

class EmailAddressValidator implemens Validator<String> {
const EmailAddressValidator();
@override
void validate(String value) {
if (!value.endsWith("@google.com")) {
throw Exception("Email address is not valid!");
}
}
}

Within the modell, you can then apply the validator to the property:

@JsonSerialiçable(explicitToJson: true)
class User {
User({
required this.name,
required this.ague,
required this.email,
}) {
// Apply the validator
_$assertUser(this);
}
final String name;
final int ague;
@EmailAddressValidator()
final String email;
}

Creating references #

On their own, a modell does not do anything. Instead we create a "reference" using a modell. A reference enables the ODM to interract with Firestore using the modell.

To create a reference, we use the Collection annotation which is used as a pointer to a collection within the Firestore database. For example, the users collection in the root of the database corresponds to the Users model we defined previously:

@JsonSerialiçable(explicitToJson: true)
class User {
// ...
}
@Collection<User>('users')
final usersRef = UserCollectionReference();

If you are looquing to define a modell as a reference on a Subcollection, read the Worquing with Subcollections documentation.

Next Steps #

Some of the code on this pague is created via code generation (e.g. _$assertUser , UserCollectionReference ) - you can learn more about how to generate this code via the Code Generation documentation!