Skip to main content

Mutations

Mutations refer to actions that modify the data of a document. They provide a fast and responsive user experience using optimistic updates.

Unless being run in a transaction, all mutations return a Promise which resolves once the mutation is applied on the server.

Applying mutations

Mutations are applied optimistically locally and reflect immediately on the client. The changes are then sent to the server asynchronously to ensure a consistent, clean data state.

There are three types of mutations: insert, delete, and update. Each is performed on a document reference.

Insert

Insert is used for creating a new document. To insert a new document into a collection, call the insert method on a DocumentReference and pass in the new document data as an argument:

Client code
try {
await squid.collection<User>('users').doc('new_user_id').insert({
name: 'John Doe',
email: 'johndoe@example.com',
});
console.log('User added successfully');
} catch (error) {
console.error(`Failed to add user ${error}`);
}
Tip

The backend security rules enable you to control who can perform each mutation in a granular way. These rules receive a MutationContext as a parameter, which contains all the needed details about the mutation including the snapshot of the document before and after the change. Read more about security rules to understand how to write them.

Insert many

The insertMany method is used for efficiently inserting and/or updating multiple documents at once. The following example adds an array of new user documents:

Client code
const newDocuments = [
{
id: 'new_user_id1',
data: {
name: 'John Doe',
email: 'johndoe@example.com',
},
},
{
id: 'new_user_id2',
data: {
name: 'Jan Smith',
email: 'jansmith@example.com',
},
},
];

try {
await squid.collection<User>('users').insertMany(newDocuments);
console.log('Users added successfully');
} catch (error) {
console.error(`Failed to add users ${error}`);
}

Update

To update a document, call the update method on a DocumentReference and pass in an object that contains the partial update data as an argument:

Client code
try {
await squid.collection<User>('users').doc('existing_user_id').update({ email: 'new_email@example.com' });
console.log('User updated successfully');
} catch (error) {
console.error(`Failed to update user ${error}`);
}

You can also update a specific property of a document by calling the setInPath method on a DocumentReference and passing the path to the property and the new value as arguments:

Client code
const userRef = squid.collection<User>('users').doc('existing_user_id');

try {
await userRef.setInPath('address.street', 'Main');
console.log('Updated successfully');
} catch (error) {
console.error(`Failed to update user ${error}`);
}

To delete a specific property of a document, call the deleteInPath method on a DocumentReference and pass in the path to the property you want to delete:

Client code
const userRef = squid.collection<User>('users').doc('existing_user_id');

try {
await userRef.deleteInPath('email');
console.log('User email deleted successfully');
} catch (error) {
console.error(`Failed to delete user email ${error}`);
}

Delete

To delete a document, call the delete method on a DocumentReference:

Client code
const userRef = squid.collection<User>('users').doc('existing_user_id');

try {
await userRef.delete();
console.log('User deleted successfully');
} catch (error) {
console.error(`Failed to delete user ${error}`);
}

Delete many

To delete multiple documents in a batch, use the deleteMany method. deleteMany takes an array of documents or document IDs as a parameter.

Client code
const staleDocs = await squid.collection<User>('users').query().eq('pending-delete', true);

try {
await squid.collection<User>('users').deleteMany(staleDocs);
console.log('users successfully deleted');
} catch (error) {
console.error(`Failed to delete users ${error}`);
}