The getCustomers tool retrieves customer records from the Firebase/Firestore database with support for pagination, sorting, and filtering.
tools/getCustomers.js
Retrieves customers for the authenticated account with cursor-based pagination support. Customers are retrieved from the Firestore path: /Accounts/{accountId}/Customers.
{
limit?: number; // Number of records to retrieve (1-100, default: 50)
cursor?: string; // Document ID for cursor-based pagination
orderBy?: string; // Field to order by (default: "customerId")
orderDirection?: "asc" | "desc"; // Sort direction (default: "asc")
cursorDirection?: "next" | "previous"; // Direction for pagination (default: "next")
includeTotal?: boolean; // Include total count of all customers (default: false)
}
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit |
number | No | 50 | Maximum number of customers to return (1-100) |
cursor |
string | No | - | Document ID to start pagination from |
orderBy |
string | No | “customerId” | Field name to sort by |
orderDirection |
enum | No | “asc” | Sort direction: “asc” or “desc” |
cursorDirection |
enum | No | “next” | Pagination direction: “next” or “previous” |
includeTotal |
boolean | No | false | Whether to include total count (expensive) |
{
customers: Customer[];
pagination: PaginationMetadata;
}
{
id: string; // Firestore document ID
path: string; // Full Firestore path
address: string; // Customer address
city: string; // City
country: string; // Country
createdAt: string | Date; // Creation timestamp (converted to locale string)
createdBy: string; // Creator user ID
customerId: number; // Unique customer ID
metadata: Record<string, any>; // Additional metadata
name: string; // Customer name
ownedBy: string; // Owner user ID
zip: string; // Postal code
}
{
limit: number; // Applied limit
hasMore: boolean; // Whether more results exist
nextCursor: string | null; // Cursor for next page
previousCursor: string | null; // Cursor for previous page
total?: number | null; // Total count (if includeTotal was true)
}
// Get first 10 customers
const result = await getCustomers(context, {
limit: 10
});
console.log(result.customers); // Array of 10 customers
console.log(result.pagination); // Pagination metadata
// First page
const page1 = await getCustomers(context, {
limit: 20,
orderBy: "customerId",
orderDirection: "asc"
});
// Next page
const page2 = await getCustomers(context, {
limit: 20,
cursor: page1.pagination.nextCursor,
cursorDirection: "next"
});
// Previous page
const page1Again = await getCustomers(context, {
limit: 20,
cursor: page2.pagination.previousCursor,
cursorDirection: "previous"
});
const result = await getCustomers(context, {
limit: 10,
includeTotal: true
});
console.log(`Showing ${result.customers.length} of ${result.pagination.total} customers`);
// Sort by name in descending order
const result = await getCustomers(context, {
limit: 10,
orderBy: "name",
orderDirection: "desc"
});
The tool transforms Firestore documents by:
id and full pathcreatedAt timestamp to locale string (de-DE format)const transformCustomer = (doc) => {
const data = doc.data();
return {
id: doc.id,
path: doc.ref.path,
...data,
createdAt: safeToLocaleString(data.createdAt) || data.createdAt,
};
};
The tool uses the shared executePaginatedQuery function from pagination.js:
startAfter or endBeforeBy default, customers are ordered by customerId in ascending order. This ensures consistent pagination behavior.
| Error | Cause | Solution |
|---|---|---|
| “Error fetching customers: [message]” | Firestore query failed | Check Firebase connection and permissions |
| Validation error | Invalid input parameters | Ensure parameters match the input schema |
| Authentication error | Invalid auth token | Verify authentication is successful |
Errors are logged to console and re-thrown with the original error message:
catch (error) {
console.error("Error fetching customers:", error);
throw new Error(error.message);
}
includeTotal: true requires an additional Firestore query and can be expensiveorderBy in production/Accounts/{accountId}/Customers/{customerId}
- address: string
- city: string
- country: string
- createdAt: timestamp
- createdBy: string
- customerId: number
- metadata: object
- name: string
- ownedBy: string
- zip: string