Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/real-database-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@tanstack-query-firebase/react": minor
---

Add Firebase Realtime Database hooks via `@tanstack-query-firebase/react/database`.

- Query hooks: `useGetQuery`, `useOnValueQuery`, and child event listeners (`useOnChildAddedQuery`, `useOnChildChangedQuery`, `useOnChildMovedQuery`, `useOnChildRemovedQuery`)
- Mutation hooks: `useSetMutation`, `useUpdateMutation`, `useRemoveMutation`, `usePushMutation`, `useRunTransactionMutation`, and priority helpers
- Connection hooks: `useGoOnlineMutation`, `useGoOfflineMutation`
- OnDisconnect hooks: `useOnDisconnectSetMutation`, `useOnDisconnectUpdateMutation`, `useOnDisconnectRemoveMutation`, `useOnDisconnectCancelMutation`, and priority variants
4 changes: 2 additions & 2 deletions .github/workflows/test-react-firebase-v12.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "17"
java-version: "21"

- name: Install Firebase CLI
uses: nick-invision/retry@v3
with:
timeout_minutes: 10
retry_wait_seconds: 60
max_attempts: 3
command: npm i -g firebase-tools@latest
command: pnpm add -g firebase-tools@14

- name: Update to Firebase v12
run: |
Expand Down
95 changes: 95 additions & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,101 @@
}
]
},
{
"tab": "react",
"group": "Realtime Database",
"pages": [
{
"title": "Getting Started",
"href": "/react/database"
},
{
"group": "Hooks",
"pages": [
{
"href": "/react/database/hooks/useGetQuery",
"title": "useGetQuery"
},
{
"href": "/react/database/hooks/useGoOfflineMutation",
"title": "useGoOfflineMutation"
},
{
"href": "/react/database/hooks/useGoOnlineMutation",
"title": "useGoOnlineMutation"
},
{
"href": "/react/database/hooks/useOnChildAddedQuery",
"title": "useOnChildAddedQuery"
},
{
"href": "/react/database/hooks/useOnChildChangedQuery",
"title": "useOnChildChangedQuery"
},
{
"href": "/react/database/hooks/useOnChildMovedQuery",
"title": "useOnChildMovedQuery"
},
{
"href": "/react/database/hooks/useOnChildRemovedQuery",
"title": "useOnChildRemovedQuery"
},
{
"href": "/react/database/hooks/useOnDisconnectCancelMutation",
"title": "useOnDisconnectCancelMutation"
},
{
"href": "/react/database/hooks/useOnDisconnectRemoveMutation",
"title": "useOnDisconnectRemoveMutation"
},
{
"href": "/react/database/hooks/useOnDisconnectSetMutation",
"title": "useOnDisconnectSetMutation"
},
{
"href": "/react/database/hooks/useOnDisconnectSetWithPriorityMutation",
"title": "useOnDisconnectSetWithPriorityMutation"
},
{
"href": "/react/database/hooks/useOnDisconnectUpdateMutation",
"title": "useOnDisconnectUpdateMutation"
},
{
"href": "/react/database/hooks/useOnValueQuery",
"title": "useOnValueQuery"
},
{
"href": "/react/database/hooks/usePushMutation",
"title": "usePushMutation"
},
{
"href": "/react/database/hooks/useRemoveMutation",
"title": "useRemoveMutation"
},
{
"href": "/react/database/hooks/useRunTransactionMutation",
"title": "useRunTransactionMutation"
},
{
"href": "/react/database/hooks/useSetMutation",
"title": "useSetMutation"
},
{
"href": "/react/database/hooks/useSetPriorityMutation",
"title": "useSetPriorityMutation"
},
{
"href": "/react/database/hooks/useSetWithPriorityMutation",
"title": "useSetWithPriorityMutation"
},
{
"href": "/react/database/hooks/useUpdateMutation",
"title": "useUpdateMutation"
}
]
}
]
},
{
"tab": "react",
"group": "Firestore",
Expand Down
11 changes: 4 additions & 7 deletions docs/react-query-firebase.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,13 @@ although initially only React is supported.
Altough still in development, the API is designed to work with the newer object-based API of TanStack Query,
and also supports newer Firebase services such as Data Connect.

### Realtime Subscription Issues
### Realtime Subscription Hooks

Firebase supports realtime event subscriptions for many of its services, such as Firestore, Realtime Database and
Authentication.
Firebase supports realtime event subscriptions for many of its services, such as Firestore, Realtime Database, and Authentication.

The `react-query-firebase` package had a [limitation](https://github.com/invertase/tanstack-query-firebase/issues/25) whereby the hooks
would not resubscribe whenever a component re-mounted.
The `react-query-firebase` package had a [limitation](https://github.com/invertase/tanstack-query-firebase/issues/25) whereby the hooks would not resubscribe whenever a component re-mounted.

The initial version of `tanstack-query-firebase` currently opts-out of any realtime subscription hooks. This issue will be re-addressed
once the core API is stable supporting all Firebase services.
TanStack Query Firebase now provides Realtime Database listener hooks (such as `useOnValueQuery` and the `useOnChild*` hooks) via `@tanstack-query-firebase/react/database`. Other services may add subscription hooks over time as the core API stabilizes.

## Migration Steps

Expand Down
18 changes: 18 additions & 0 deletions docs/react/database/hooks/useGetQuery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: useGetQuery
---

Read data once from a Realtime Database location.

## Usage

```tsx
import { ref } from "firebase/database";
import { useGetQuery } from "@tanstack-query-firebase/react/database";

const userRef = ref(database, `users/${uid}`);
const { data: snapshot, isLoading } = useGetQuery(userRef, {
queryKey: ["database", "users", uid],
});
const value = snapshot?.val();
```
14 changes: 14 additions & 0 deletions docs/react/database/hooks/useGoOfflineMutation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: useGoOfflineMutation
---

Disconnect the Realtime Database client from the server.

## Usage

```tsx
import { useGoOfflineMutation } from "@tanstack-query-firebase/react/database";

const { mutate } = useGoOfflineMutation(database);
mutate();
```
14 changes: 14 additions & 0 deletions docs/react/database/hooks/useGoOnlineMutation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: useGoOnlineMutation
---

Reconnect the Realtime Database client to the server.

## Usage

```tsx
import { useGoOnlineMutation } from "@tanstack-query-firebase/react/database";

const { mutate } = useGoOnlineMutation(database);
mutate();
```
17 changes: 17 additions & 0 deletions docs/react/database/hooks/useOnChildAddedQuery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: useOnChildAddedQuery
---

Subscribe to `child_added` events on a Realtime Database query.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnChildAddedQuery } from "@tanstack-query-firebase/react/database";

const messagesRef = ref(database, "messages");
const { data: snapshot } = useOnChildAddedQuery(messagesRef, {
queryKey: ["database", "childAdded", "messages"],
});
```
17 changes: 17 additions & 0 deletions docs/react/database/hooks/useOnChildChangedQuery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: useOnChildChangedQuery
---

Subscribe to `child_changed` events on a Realtime Database query.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnChildChangedQuery } from "@tanstack-query-firebase/react/database";

const messagesRef = ref(database, "messages");
const { data: snapshot } = useOnChildChangedQuery(messagesRef, {
queryKey: ["database", "childChanged", "messages"],
});
```
17 changes: 17 additions & 0 deletions docs/react/database/hooks/useOnChildMovedQuery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: useOnChildMovedQuery
---

Subscribe to `child_moved` events. Requires a query ordered with `orderByPriority()`.

## Usage

```tsx
import { orderByPriority, query, ref } from "firebase/database";
import { useOnChildMovedQuery } from "@tanstack-query-firebase/react/database";

const tasksRef = query(ref(database, "tasks"), orderByPriority());
const { data: snapshot } = useOnChildMovedQuery(tasksRef, {
queryKey: ["database", "childMoved", "tasks"],
});
```
17 changes: 17 additions & 0 deletions docs/react/database/hooks/useOnChildRemovedQuery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: useOnChildRemovedQuery
---

Subscribe to `child_removed` events on a Realtime Database query.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnChildRemovedQuery } from "@tanstack-query-firebase/react/database";

const messagesRef = ref(database, "messages");
const { data: snapshot } = useOnChildRemovedQuery(messagesRef, {
queryKey: ["database", "childRemoved", "messages"],
});
```
16 changes: 16 additions & 0 deletions docs/react/database/hooks/useOnDisconnectCancelMutation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: useOnDisconnectCancelMutation
---

Cancel all pending on-disconnect operations at a location.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnDisconnectCancelMutation } from "@tanstack-query-firebase/react/database";

const statusRef = ref(database, `users/${uid}/status`);
const { mutate } = useOnDisconnectCancelMutation(statusRef);
mutate();
```
16 changes: 16 additions & 0 deletions docs/react/database/hooks/useOnDisconnectRemoveMutation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: useOnDisconnectRemoveMutation
---

Queue removal of data when the client disconnects.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnDisconnectRemoveMutation } from "@tanstack-query-firebase/react/database";

const sessionRef = ref(database, `sessions/${sessionId}`);
const { mutate } = useOnDisconnectRemoveMutation(sessionRef);
mutate();
```
16 changes: 16 additions & 0 deletions docs/react/database/hooks/useOnDisconnectSetMutation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: useOnDisconnectSetMutation
---

Queue a `set` operation to run when the client disconnects.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnDisconnectSetMutation } from "@tanstack-query-firebase/react/database";

const statusRef = ref(database, `users/${uid}/status`);
const { mutate } = useOnDisconnectSetMutation(statusRef);
mutate("offline");
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: useOnDisconnectSetWithPriorityMutation
---

Queue a `setWithPriority` operation to run when the client disconnects.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnDisconnectSetWithPriorityMutation } from "@tanstack-query-firebase/react/database";

const taskRef = ref(database, "tasks/task-1");
const { mutate } = useOnDisconnectSetWithPriorityMutation(taskRef);
mutate({ value: { title: "Cleanup" }, priority: 0 });
```
16 changes: 16 additions & 0 deletions docs/react/database/hooks/useOnDisconnectUpdateMutation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: useOnDisconnectUpdateMutation
---

Queue a multi-path `update` to run when the client disconnects.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnDisconnectUpdateMutation } from "@tanstack-query-firebase/react/database";

const userRef = ref(database, `users/${uid}`);
const { mutate } = useOnDisconnectUpdateMutation(userRef);
mutate({ status: "offline", lastSeen: Date.now() });
```
17 changes: 17 additions & 0 deletions docs/react/database/hooks/useOnValueQuery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: useOnValueQuery
---

Subscribe to value events at a Realtime Database location.

## Usage

```tsx
import { ref } from "firebase/database";
import { useOnValueQuery } from "@tanstack-query-firebase/react/database";

const userRef = ref(database, `users/${uid}`);
const { data: snapshot } = useOnValueQuery(userRef, {
queryKey: ["database", "onValue", "users", uid],
});
```
16 changes: 16 additions & 0 deletions docs/react/database/hooks/usePushMutation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: usePushMutation
---

Append a child with an auto-generated key to a list.

## Usage

```tsx
import { ref } from "firebase/database";
import { usePushMutation } from "@tanstack-query-firebase/react/database";

const messagesRef = ref(database, "messages");
const { mutate, data: newRef } = usePushMutation(messagesRef);
mutate({ text: "Hello" });
```
Loading
Loading