Skip to content

Commit 47cab3f

Browse files
committed
Fixed issue where updated variables weren't getting picked up
1 parent 0c12a7f commit 47cab3f

File tree

6 files changed

+178
-28
lines changed

6 files changed

+178
-28
lines changed

dataconnect-sdk/js/default-connector/README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ A connector is a collection of Queries and Mutations. One SDK is generated for e
2828
You can find more information about connectors in the [Data Connect documentation](https://firebase.google.com/docs/data-connect#how-does).
2929

3030
```javascript
31-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
31+
import { getDataConnect } from 'firebase/data-connect';
3232
import { connectorConfig } from '@dataconnect/default-connector';
3333

3434
const dataConnect = getDataConnect(connectorConfig);
@@ -41,7 +41,7 @@ To connect to the emulator, you can use the following code.
4141
You can also follow the emulator instructions from the [Data Connect documentation](https://firebase.google.com/docs/data-connect/web-sdk#instrument-clients).
4242

4343
```javascript
44-
import { connectDataConnectEmulator, getDataConnect, DataConnect } from 'firebase/data-connect';
44+
import { connectDataConnectEmulator, getDataConnect } from 'firebase/data-connect';
4545
import { connectorConfig } from '@dataconnect/default-connector';
4646

4747
const dataConnect = getDataConnect(connectorConfig);
@@ -98,7 +98,7 @@ export interface ListMoviesData {
9898
### Using `ListMovies`'s action shortcut function
9999

100100
```javascript
101-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
101+
import { getDataConnect } from 'firebase/data-connect';
102102
import { connectorConfig, listMovies } from '@dataconnect/default-connector';
103103

104104

@@ -122,7 +122,7 @@ listMovies().then((response) => {
122122
### Using `ListMovies`'s `QueryRef` function
123123

124124
```javascript
125-
import { getDataConnect, DataConnect, executeQuery } from 'firebase/data-connect';
125+
import { getDataConnect, executeQuery } from 'firebase/data-connect';
126126
import { connectorConfig, listMoviesRef } from '@dataconnect/default-connector';
127127

128128

@@ -185,7 +185,7 @@ export interface GetMovieByIdData {
185185
### Using `GetMovieById`'s action shortcut function
186186

187187
```javascript
188-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
188+
import { getDataConnect } from 'firebase/data-connect';
189189
import { connectorConfig, getMovieById, GetMovieByIdVariables } from '@dataconnect/default-connector';
190190

191191
// The `GetMovieById` query requires an argument of type `GetMovieByIdVariables`:
@@ -215,7 +215,7 @@ getMovieById(getMovieByIdVars).then((response) => {
215215
### Using `GetMovieById`'s `QueryRef` function
216216

217217
```javascript
218-
import { getDataConnect, DataConnect, executeQuery } from 'firebase/data-connect';
218+
import { getDataConnect, executeQuery } from 'firebase/data-connect';
219219
import { connectorConfig, getMovieByIdRef, GetMovieByIdVariables } from '@dataconnect/default-connector';
220220

221221
// The `GetMovieById` query requires an argument of type `GetMovieByIdVariables`:
@@ -275,7 +275,7 @@ export interface GetMetaData {
275275
### Using `GetMeta`'s action shortcut function
276276

277277
```javascript
278-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
278+
import { getDataConnect } from 'firebase/data-connect';
279279
import { connectorConfig, getMeta } from '@dataconnect/default-connector';
280280

281281

@@ -299,7 +299,7 @@ getMeta().then((response) => {
299299
### Using `GetMeta`'s `QueryRef` function
300300

301301
```javascript
302-
import { getDataConnect, DataConnect, executeQuery } from 'firebase/data-connect';
302+
import { getDataConnect, executeQuery } from 'firebase/data-connect';
303303
import { connectorConfig, getMetaRef } from '@dataconnect/default-connector';
304304

305305

@@ -374,7 +374,7 @@ export interface CreateMovieData {
374374
### Using `CreateMovie`'s action shortcut function
375375

376376
```javascript
377-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
377+
import { getDataConnect } from 'firebase/data-connect';
378378
import { connectorConfig, createMovie, CreateMovieVariables } from '@dataconnect/default-connector';
379379

380380
// The `CreateMovie` mutation requires an argument of type `CreateMovieVariables`:
@@ -406,7 +406,7 @@ createMovie(createMovieVars).then((response) => {
406406
### Using `CreateMovie`'s `MutationRef` function
407407

408408
```javascript
409-
import { getDataConnect, DataConnect, executeMutation } from 'firebase/data-connect';
409+
import { getDataConnect, executeMutation } from 'firebase/data-connect';
410410
import { connectorConfig, createMovieRef, CreateMovieVariables } from '@dataconnect/default-connector';
411411

412412
// The `CreateMovie` mutation requires an argument of type `CreateMovieVariables`:
@@ -474,7 +474,7 @@ export interface UpsertMovieData {
474474
### Using `UpsertMovie`'s action shortcut function
475475

476476
```javascript
477-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
477+
import { getDataConnect } from 'firebase/data-connect';
478478
import { connectorConfig, upsertMovie, UpsertMovieVariables } from '@dataconnect/default-connector';
479479

480480
// The `UpsertMovie` mutation requires an argument of type `UpsertMovieVariables`:
@@ -506,7 +506,7 @@ upsertMovie(upsertMovieVars).then((response) => {
506506
### Using `UpsertMovie`'s `MutationRef` function
507507

508508
```javascript
509-
import { getDataConnect, DataConnect, executeMutation } from 'firebase/data-connect';
509+
import { getDataConnect, executeMutation } from 'firebase/data-connect';
510510
import { connectorConfig, upsertMovieRef, UpsertMovieVariables } from '@dataconnect/default-connector';
511511

512512
// The `UpsertMovie` mutation requires an argument of type `UpsertMovieVariables`:
@@ -572,7 +572,7 @@ export interface DeleteMovieData {
572572
### Using `DeleteMovie`'s action shortcut function
573573

574574
```javascript
575-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
575+
import { getDataConnect } from 'firebase/data-connect';
576576
import { connectorConfig, deleteMovie, DeleteMovieVariables } from '@dataconnect/default-connector';
577577

578578
// The `DeleteMovie` mutation requires an argument of type `DeleteMovieVariables`:
@@ -602,7 +602,7 @@ deleteMovie(deleteMovieVars).then((response) => {
602602
### Using `DeleteMovie`'s `MutationRef` function
603603

604604
```javascript
605-
import { getDataConnect, DataConnect, executeMutation } from 'firebase/data-connect';
605+
import { getDataConnect, executeMutation } from 'firebase/data-connect';
606606
import { connectorConfig, deleteMovieRef, DeleteMovieVariables } from '@dataconnect/default-connector';
607607

608608
// The `DeleteMovie` mutation requires an argument of type `DeleteMovieVariables`:
@@ -660,7 +660,7 @@ export interface AddMetaData {
660660
### Using `AddMeta`'s action shortcut function
661661

662662
```javascript
663-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
663+
import { getDataConnect } from 'firebase/data-connect';
664664
import { connectorConfig, addMeta } from '@dataconnect/default-connector';
665665

666666

@@ -684,7 +684,7 @@ addMeta().then((response) => {
684684
### Using `AddMeta`'s `MutationRef` function
685685

686686
```javascript
687-
import { getDataConnect, DataConnect, executeMutation } from 'firebase/data-connect';
687+
import { getDataConnect, executeMutation } from 'firebase/data-connect';
688688
import { connectorConfig, addMetaRef } from '@dataconnect/default-connector';
689689

690690

@@ -742,7 +742,7 @@ export interface DeleteMetaData {
742742
### Using `DeleteMeta`'s action shortcut function
743743

744744
```javascript
745-
import { getDataConnect, DataConnect } from 'firebase/data-connect';
745+
import { getDataConnect } from 'firebase/data-connect';
746746
import { connectorConfig, deleteMeta, DeleteMetaVariables } from '@dataconnect/default-connector';
747747

748748
// The `DeleteMeta` mutation requires an argument of type `DeleteMetaVariables`:
@@ -772,7 +772,7 @@ deleteMeta(deleteMetaVars).then((response) => {
772772
### Using `DeleteMeta`'s `MutationRef` function
773773

774774
```javascript
775-
import { getDataConnect, DataConnect, executeMutation } from 'firebase/data-connect';
775+
import { getDataConnect, executeMutation } from 'firebase/data-connect';
776776
import { connectorConfig, deleteMetaRef, DeleteMetaVariables } from '@dataconnect/default-connector';
777777

778778
// The `DeleteMeta` mutation requires an argument of type `DeleteMetaVariables`:

dataconnect-sdk/js/default-connector/index.cjs.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,62 +12,77 @@ exports.createMovieRef = function createMovieRef(dcOrVars, vars) {
1212
dcInstance._useGeneratedSdk();
1313
return mutationRef(dcInstance, 'CreateMovie', inputVars);
1414
}
15+
1516
exports.createMovie = function createMovie(dcOrVars, vars) {
1617
return executeMutation(createMovieRef(dcOrVars, vars));
1718
};
19+
1820
exports.upsertMovieRef = function upsertMovieRef(dcOrVars, vars) {
1921
const { dc: dcInstance, vars: inputVars} = validateArgs(connectorConfig, dcOrVars, vars, true);
2022
dcInstance._useGeneratedSdk();
2123
return mutationRef(dcInstance, 'UpsertMovie', inputVars);
2224
}
25+
2326
exports.upsertMovie = function upsertMovie(dcOrVars, vars) {
2427
return executeMutation(upsertMovieRef(dcOrVars, vars));
2528
};
29+
2630
exports.deleteMovieRef = function deleteMovieRef(dcOrVars, vars) {
2731
const { dc: dcInstance, vars: inputVars} = validateArgs(connectorConfig, dcOrVars, vars, true);
2832
dcInstance._useGeneratedSdk();
2933
return mutationRef(dcInstance, 'DeleteMovie', inputVars);
3034
}
35+
3136
exports.deleteMovie = function deleteMovie(dcOrVars, vars) {
3237
return executeMutation(deleteMovieRef(dcOrVars, vars));
3338
};
39+
3440
exports.addMetaRef = function addMetaRef(dc) {
3541
const { dc: dcInstance} = validateArgs(connectorConfig, dc, undefined);
3642
dcInstance._useGeneratedSdk();
3743
return mutationRef(dcInstance, 'AddMeta');
3844
}
45+
3946
exports.addMeta = function addMeta(dc) {
4047
return executeMutation(addMetaRef(dc));
4148
};
49+
4250
exports.deleteMetaRef = function deleteMetaRef(dcOrVars, vars) {
4351
const { dc: dcInstance, vars: inputVars} = validateArgs(connectorConfig, dcOrVars, vars, true);
4452
dcInstance._useGeneratedSdk();
4553
return mutationRef(dcInstance, 'DeleteMeta', inputVars);
4654
}
55+
4756
exports.deleteMeta = function deleteMeta(dcOrVars, vars) {
4857
return executeMutation(deleteMetaRef(dcOrVars, vars));
4958
};
59+
5060
exports.listMoviesRef = function listMoviesRef(dc) {
5161
const { dc: dcInstance} = validateArgs(connectorConfig, dc, undefined);
5262
dcInstance._useGeneratedSdk();
5363
return queryRef(dcInstance, 'ListMovies');
5464
}
65+
5566
exports.listMovies = function listMovies(dc) {
5667
return executeQuery(listMoviesRef(dc));
5768
};
69+
5870
exports.getMovieByIdRef = function getMovieByIdRef(dcOrVars, vars) {
5971
const { dc: dcInstance, vars: inputVars} = validateArgs(connectorConfig, dcOrVars, vars, true);
6072
dcInstance._useGeneratedSdk();
6173
return queryRef(dcInstance, 'GetMovieById', inputVars);
6274
}
75+
6376
exports.getMovieById = function getMovieById(dcOrVars, vars) {
6477
return executeQuery(getMovieByIdRef(dcOrVars, vars));
6578
};
79+
6680
exports.getMetaRef = function getMetaRef(dc) {
6781
const { dc: dcInstance} = validateArgs(connectorConfig, dc, undefined);
6882
dcInstance._useGeneratedSdk();
6983
return queryRef(dcInstance, 'GetMeta');
7084
}
85+
7186
exports.getMeta = function getMeta(dc) {
7287
return executeQuery(getMetaRef(dc));
7388
};

packages/react/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,9 @@
4646
"peerDependencies": {
4747
"@tanstack/react-query": "^5",
4848
"firebase": "^11.3.0"
49+
},
50+
"dependencies": {
51+
"@types/deep-equal": "^1.0.4",
52+
"deep-equal": "^2.2.3"
4953
}
5054
}

packages/react/src/data-connect/useDataConnectQuery.test.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,44 @@ describe("useDataConnectQuery", () => {
269269
{ id: movieId },
270270
]);
271271
});
272+
273+
test("fetches new data when variables change", async () => {
274+
const movieData1 = {
275+
title: "tanstack query firebase 1",
276+
genre: "library 1",
277+
imageUrl: "https://invertase.io/1",
278+
};
279+
const createdMovie = await createMovie(movieData1);
280+
const movieData2 = {
281+
title: "tanstack query firebase 2",
282+
genre: "library 2",
283+
imageUrl: "https://invertase.io/2",
284+
};
285+
const createdMovie2 = await createMovie(movieData2);
286+
287+
const movieId = createdMovie?.data?.movie_insert?.id;
288+
const movieId2 = createdMovie2?.data?.movie_insert?.id;
289+
getMovieByIdRef({ id: movieId2 });
290+
const ref = getMovieByIdRef({ id: movieId });
291+
const { result } = renderHook(() => useDataConnectQuery(ref), {
292+
wrapper,
293+
});
294+
295+
await waitFor(() => {
296+
expect(result.current.isSuccess).toBe(true);
297+
expect(result.current.data?.movie?.title).toBe(movieData1?.title);
298+
expect(result.current.data?.movie?.genre).toBe(movieData1?.genre);
299+
expect(result.current.data?.movie?.imageUrl).toBe(movieData1?.imageUrl);
300+
});
301+
await act(async () => {
302+
ref.variables.id = createdMovie2.data.movie_insert.id;
303+
result.current.refetch();
304+
});
305+
await waitFor(() => {
306+
expect(result.current.isSuccess).toBe(true);
307+
expect(result.current.data?.movie?.title).toBe(movieData2?.title);
308+
expect(result.current.data?.movie?.genre).toBe(movieData2?.genre);
309+
expect(result.current.data?.movie?.imageUrl).toBe(movieData2?.imageUrl);
310+
});
311+
});
272312
});

packages/react/src/data-connect/useDataConnectQuery.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
type UseQueryOptions,
44
useQuery,
55
} from "@tanstack/react-query";
6+
import deepEqual from "deep-equal";
67
import type { FirebaseError } from "firebase/app";
78
import {
89
type CallerSdkType,
@@ -11,7 +12,7 @@ import {
1112
type QueryResult,
1213
executeQuery,
1314
} from "firebase/data-connect";
14-
import { useState } from "react";
15+
import { useEffect, useMemo, useState } from "react";
1516
import type { PartialBy } from "../../utils";
1617
import type {
1718
QueryResultRequiredRef,
@@ -22,6 +23,11 @@ export type useDataConnectQueryOptions<
2223
TData = object,
2324
TError = FirebaseError,
2425
> = PartialBy<Omit<UseQueryOptions<TData, TError>, "queryFn">, "queryKey">;
26+
function getRef<Data, Variables>(
27+
refOrResult: QueryRef<Data, Variables> | QueryResult<Data, Variables>,
28+
): QueryRef<Data, Variables> {
29+
return "ref" in refOrResult ? refOrResult.ref : refOrResult;
30+
}
2531

2632
export function useDataConnectQuery<Data = unknown, Variables = unknown>(
2733
refOrResult: QueryRef<Data, Variables> | QueryResult<Data, Variables>,
@@ -31,17 +37,24 @@ export function useDataConnectQuery<Data = unknown, Variables = unknown>(
3137
const [dataConnectResult, setDataConnectResult] = useState<
3238
QueryResultRequiredRef<Data, Variables>
3339
>("ref" in refOrResult ? refOrResult : { ref: refOrResult });
40+
const [ref, setRef] = useState(dataConnectResult.ref);
3441
// TODO(mtewani): in the future we should allow for users to pass in `QueryResult` objects into `initialData`.
35-
let initialData: Data | InitialDataFunction<Data> | undefined;
36-
const { ref } = dataConnectResult;
42+
const [initialData] = useState(
43+
dataConnectResult.data || options?.initialData,
44+
);
3745

38-
if ("ref" in refOrResult) {
39-
initialData = {
40-
...refOrResult.data,
41-
};
42-
} else {
43-
initialData = options?.initialData;
44-
}
46+
useEffect(() => {
47+
setRef((oldRef) => {
48+
const newRef = getRef(refOrResult);
49+
if (
50+
newRef.name !== oldRef.name ||
51+
!deepEqual(oldRef, newRef, { strict: true })
52+
) {
53+
return newRef;
54+
}
55+
return oldRef;
56+
});
57+
}, [refOrResult]);
4558

4659
// @ts-expect-error function is hidden under `DataConnect`.
4760
ref.dataConnect._setCallerSdkType(_callerSdkType);

0 commit comments

Comments
 (0)