Skip to content

Firestore Collections

firekitCollection subscribes to a Firestore collection and keeps data in sync with the server in real time.

<script lang="ts">
import { firekitCollection } from 'svelte-firekit';
import { where, orderBy } from 'firebase/firestore';
interface Post {
id: string;
title: string;
published: boolean;
createdAt: Date;
}
const posts = firekitCollection<Post>('posts', [
where('published', '==', true),
orderBy('createdAt', 'desc'),
]);
</script>
{#if posts.loading}
<p>Loading…</p>
{:else}
{#each posts.data as post (post.id)}
<article>
<h2>{post.title}</h2>
</article>
{/each}
{/if}
PropertyTypeDescription
dataT[]Array of documents (each includes an id field)
loadingbooleantrue while the initial snapshot is being fetched
errorError | nullSet if the subscription fails
countnumberNumber of documents currently in data
currentPagenumberCurrent page number when pagination is active
hasMorebooleanWhether more pages are available
import { firekitCollectionOnce } from 'svelte-firekit';
const posts = firekitCollectionOnce<Post>('posts', [where('published', '==', true)]);

Call setPagination to switch the collection from a live listener to page-by-page fetching.

// Fetch 10 documents per page
await posts.setPagination(10);
// Navigate
await posts.nextPage(); // next page (replaces data)
await posts.prevPage(); // previous page
await posts.loadMore(); // append next page (infinite scroll)
await posts.resetPagination(); // back to page 1
// State
posts.currentPage // 1, 2, 3 …
posts.hasMore // false on the last page
<script lang="ts">
import { firekitCollection } from 'svelte-firekit';
import { orderBy } from 'firebase/firestore';
const posts = firekitCollection<Post>('posts', [orderBy('createdAt', 'desc')]);
async function init() {
await posts.setPagination(10);
}
init();
</script>
{#each posts.data as post (post.id)}
<article>{post.title}</article>
{/each}
{#if posts.hasMore}
<button onclick={() => posts.loadMore()}>Load more</button>
{/if}

FirekitQueryBuilder provides a chainable API for building query constraints — useful when the query depends on runtime values.

import { FirekitQueryBuilder, firekitCollection } from 'svelte-firekit';
const constraints = new FirekitQueryBuilder<Post>()
.where('published', '==', true)
.where('authorId', '==', currentUserId)
.orderBy('createdAt', 'desc')
.limit(20)
.build();
const posts = firekitCollection<Post>('posts', constraints);
MethodDescription
.where(field, op, value)Filter by field
.orderBy(field, direction?)Sort results
.limit(n)Maximum number of documents
.limitToLast(n)Last N documents
.startAt(...values)Cursor start (inclusive)
.startAfter(...values)Cursor start (exclusive)
.endAt(...values)Cursor end (inclusive)
.endBefore(...values)Cursor end (exclusive)
.build()Return the QueryConstraint[] array

Query across all sub-collections with the same name using firekitCollectionGroup:

<script lang="ts">
import { firekitCollectionGroup } from 'svelte-firekit';
import { where } from 'firebase/firestore';
interface Comment {
id: string;
text: string;
authorId: string;
}
// Queries 'comments' sub-collection across all parent documents
const allComments = firekitCollectionGroup<Comment>('comments', [
where('authorId', '==', currentUserId),
]);
</script>
{#each allComments.data as comment (comment.id)}
<p>{comment.text}</p>
{/each}
<script lang="ts">
import { Collection } from 'svelte-firekit';
import { where, orderBy } from 'firebase/firestore';
</script>
<Collection
path="posts"
query={[where('published', '==', true), orderBy('createdAt', 'desc')]}
>
{#snippet data(posts)}
{#each posts as post (post.id)}
<article><h2>{post.title}</h2></article>
{/each}
{/snippet}
{#snippet loading()}
<p>Loading…</p>
{/snippet}
</Collection>
PropTypeRequiredDescription
pathstringYesFirestore collection path
queryQueryConstraint[]NoFirestore query constraints
SnippetArgumentsDescription
dataT[]Rendered with the document array
loadingRendered while loading
errorErrorRendered when the subscription fails