Client functions allow your application to interact with Firestore directly from the client side. The boilerplate includes ready-to-use functions in lib/services/tasks-client.ts as examples. These functions handle authentication, validation, and data transformation automatically.
1
Example: Create Task Function
Here’s a basic example of a client-side function to create a task:
// 🔨 CREATE Task
export async function createTaskClient(task: Partial<Task>, serverCustomToken: string) {
const user = await getAuthUser(serverCustomToken);
if (!user) throw new Error("User must be logged in");
if (!task.name) throw new Error("Missing required param: name");
const now = new Date();
const writeTask: Omit<Task, "id"> = {
userId: user.uid,
name: task.name,
description: task.description ?? "",
createdAt: now,
updatedAt: now,
};
const db = getFirestore(getFirebaseApp());
const docRef = await addDoc(collection(db, "tasks"), toFirestore(writeTask));
return { id: docRef.id, ...writeTask };
}
This function:
- Validates the user and required parameters.
- Prepares the task object with timestamps.
- Writes the task to Firestore.
- Returns the newly created task with its Firestore
id.
2
Calling the Create Task Function
Here’s how you can call createTaskClient from a React component:
const handleAddTask = async () => {
if (!newTask.name?.trim()) return;
if (!user?.uid || !user.customToken) return;
setLoading(true);
createTaskClient(newTask, user.customToken).then(async () => {
// handle success, e.g., refresh task list or reset form
}).catch((error) => {
console.error(error);
// handle error
}).finally(() => {
setLoading(false);
});
};
Notes:
- Always ensure the user is authenticated and has a valid
customToken. - Handle loading and error states for a smooth user experience.
Next, we can cover Firestore Admin Functions, showing how to define and call server-side functions with elevated privileges.