Getting Started With TanStack Query Firebase and Firebase Data Connect


TanStack Query Firebase provides a set of hooks for handling asynchronous tasks with Firebase in your applications. According to the official documentation: “Firebase Data Connect is Firebase's first relational database solution for developers who want to create secure and scalable apps with Cloud SQL for PostgreSQL and type-safe mobile and web SDKs.
Getting Started
In this guide, we are going to create a react app that leverages useConnectQuery
and useConnectMutation
from TanStack Query Firebase to perform CRUD operations to Firebase Data Connect.
Let’s jump right in!
Step 1: Bootstrapping the app.
Firstly, we are going to setup a react app using vite. To achieve this, we are going to run the command below.
pnpm create vite firebase-dataconnect-movies
On running the above command, we shall follow through the prompts and select React
with Typescript
options and a project will be scaffolded and will have the files as below.
Open your terminal and while at the project root, run pnpm install
to install dependencies.
Once the dependencies are successfully installed, run pnpm dev
and a link will be availed through which you can view the project in your browser. This will look as below;
With that, we have successfully scaffolded our react application.
Step 2: Generating Data Connect SDK for our application.
Firebase Data Connect uses GraphQL for data modeling and definition of CRUD operations. With Firebase Data Connect and GraphQL, we are going to define schemas, queries and mutations, Data Connect will automatically generate custom SDKs for usage in the client logic.
Firstly, ensure that you have the Firebase Data Connect for VSCode Extension installed. On clicking the Firebase Data Connect Extension icon, you will see a screen as below;
Here, we shall go ahead and click the Run firebase init
button which will start a couple prompts in our terminal. The very first option will be to use an existing project or create new project, for which we shall select create new project and any name of your choice and in our case we are going to use fdc-movies-app
. There after a firebase project will be created.
You will then be asked what connector should be setup for a generated SDK for, we shall select firebase-dataconnect-movies/default
which is the suggested default option.
When all the above are successfully completed, you would have gone through the prompts as below;
You can proceed to click enter and the current initialization terminal will close automatically.
At this point, in sidebar under the Firebase Data Connect Extension, you will have the following options
It is also important to note that a couple of files have also been generated into our project as below;
.firebase
- folderdataconnect
- folderdataconnect-generated
- folder.firebaserc
- filefirebase.json
- file
We now need to go into the dataconnect
folder and uncomment all the contents of the mutations.gql
, queries.gql
and schema.gql
files. All code in those files is initially commented out. After uncommenting, these will look as below;
At this point, the generation of the Data Connect SDK is complete and it is currently connected to your application.
Since we are going to be testing locally, we shall need to start the emulators by clicking the Start emulators
button under Firebase Data Connect Extension. On clicking this button, the emulators will and the extension will show as below;
Step 3: Initialization of Firebase and TanStack Query.
In Step 2
, we did create a firebase project called fdc-movies-app
. When we head over to the firebase console, we should be able to find our project listed.
While in our project, we shall need to register an app. We are going to register a web app and we shall do that by selecting the Web
option. We shall proceed to register our app with a name of our choice which could be fdc-movies-app
and then the Firebase SDK config object will be availed as below;
We shall then head over to our project and add a .env
file to store our environment variables and replace the placeholder values with the actual values from the above firebaseConfig
object. Please note all these will be prefixed with VITE_
since we are using Vite.
VITE_FIREBASE_API_KEY="your-firebase-apiKey"
VITE_FIREBASE_AUTH_DOMAIN="your-firebase-authDomain"
VITE_FIREBASE_PROJECT_ID="your-firebase-projectId"
VITE_FIREBASE_STORAGE_BUCKET="your-firebase-storageBucket"
VITE_FIREBASE_MESSAGING_SENDER_ID="your-firebase-messagingSenderId"
VITE_FIREBASE_APP_ID="your-firebase-appId"
Next, we are going to install the firebase
and @tanstack/react-query
packages using the commands below;
pnpm i firebase @tanstack/react-query
We are then going to modify our src/main.tsx
so as to initialize a firebase app and initialize a Data Connect emulator connection as seen below;
Step 4: CRUD operations with useConnectMutation
and useConnectQuery
useConnectMutation
and useConnectQuery
are hooks availed by TanStack Query Firebase. useConnectMutation
enables you to perform create
, update
and delete
operations while useConnectQuery
enables you to read
/retrieve
data records stored in your database.
To get started with TanStack Query Firebase, we shall install the library using the following command.
pnpm i @tanstack-query-firebase/react
We are going to use the useConnectQuery
hook to fetch the movies data as seen below. This will be done in the src/App.tsx
file.
import "./App.css";
import {useConnectQuery} from "@tanstack-query-firebase/react";
import {listMoviesRef} from "@firebasegen/default-connector";
function App() {
const { data, isLoading, isSuccess, isError } = useConnectQuery(listMoviesRef());
return(
<div>
{isLoading && <p>Loading...</p>}
{isError && <p>Sorry, an error occurred.</p>}
{isSuccess && data.movies.length > 0 ? (
<div className="movies-grid">
{data.movies.map((movie, index) => (
<div className="movie-card" key={index}>
<img src={movie.imageUrl} alt={movie.title} />
<h3>{movie.title}</h3>
<p>Genre: {movie.genre}</p>
</div>
))}
</div>
) : (
<p>No movies found!</p>
)}
</div>
)
}
export default App;
For creating movies, we are going to use the useConnectMutation
hook, and we are going to set it up as below;
import "./App.css";
import {useConnectMutation} from "@tanstack-query-firebase/react";
import {createMovieRef} from "@firebasegen/default-connector";
function App() {
const [movie, setMovie] = useState({
title: "",
imageUrl: "",
genre: "",
});
const [error, setError] = useState("");
const createMovieMutation = useConnectMutation(createMovieRef, {
invalidate: [listMoviesRef()],
onSuccess: () => {
setMovie({ title: "", imageUrl: "", genre: "" });
},
onError: (error) => {
setError("Failed to add movie. Please try again.");
console.error(error);
},
});
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setMovie((prevMovie) => ({
...prevMovie,
[name]: value,
}));
};
const handleFormSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!movie.title || !movie.imageUrl || !movie.genre) {
setError("All fields are required.");
return;
}
setError("");
createMovieMutation.mutate(movie);
};
return(
<div className="movie-form">
<h2>Add a New Movie</h2>
<form onSubmit={handleFormSubmit}>
<div>
<label>Title:</label>
<input
type="text"
name="title"
value={movie.title}
onChange={handleInputChange}
placeholder="Movie Title"
/>
</div>
<div>
<label>Image URL:</label>
<input
type="text"
name="imageUrl"
value={movie.imageUrl}
onChange={handleInputChange}
placeholder="Movie Image URL"
/>
</div>
<div>
<label>Genre:</label>
<input
type="text"
name="genre"
value={movie.genre}
onChange={handleInputChange}
placeholder="Movie Genre"
/>
</div>
<button type="submit" disabled={createMovieMutation.isPending}>
{createMovieMutation.isPending ? "Adding..." : "Add Movie"}
</button>
</form>
{error && <p className="error-message">{error}</p>}
</div>
)
}
export default App;
For the full code, please checkout the src/App.tsx on GitHub.
When we visit our browser, the interface will be as in the image below. Here, new movies can be added and will appear in the list right away.
Please note that the Data Connect emulator has to be running as seen in Step 2
, otherwise the connection to the database will fail.
Congratulations!
References
Subscribe to my newsletter
Read articles from Hassan Bahati directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
