Multi-user database collaboration made easy with Fireproof

J Chris Anderson
Posted on:16 Oct 2023

J Chris Anderson’s relentless pursuit of simple programming models for event driven apps running near the user led to his early success with Apache CouchDB and Couchbase Mobile, and now to his creation of Fireproof.

PartyKit’s effortless connections are the perfect complement to Fireproof’s immutable storage, and we both love breaking the easy barrier. Our shared excitement about opening up new worlds for developers makes me even happier to be writing a guest post to bring you the news: building a PartyKit Fireproof connector was so easy we shipped it in a week.

When your database is a source of truth, hard things become easy and the impossible becomes reachable. I created the Fireproof database to empower web developers – just write a simple UI in your usual style and end up with a multi-user data-driven application. Once the data is in Fireproof, you can securely reference it from any backend or cloud.

Some of the benefits of our new adapter:

Knowing when to use ephemeral client-local state, in-party storage, or a cloud database isn’t always straightforward. Fireproof’s verifiable snapshot links make it a new relaxing choice for hosting your party data. In a real-world application like a bike messenger service, one might use a cloud for route optimization, PartyKit to connect with messengers and track their status and location, and Fireproof in the messenger app for offline delivery details and photo or recipient signature workflow. Each delivery could be archived as a URL-sized snapshot link for verifiable query and replay. Many similar use cases—from real estate leasing to supply chain compliance—can benefit from offline availability, cryptographic data integrity, and the ability to archive anywhere.

Get into the code

Our first demo using the Fireproof PartyKit connector is even simpler. It’s a magnetic poetry app, based on Matt Webb’s excellent mosaic drawing app, that allows you to collaborate on word tile arrangements and save your beautiful word paintings, masterpieces that they are, for posterity! Drag and drop tile motion is shared in PartyKit, and poems are saved and loaded from Fireproof. Try out the magnetic poetry app here, or continue reading to run your own copy and start adapting the code for your own purposes.

The poem editor drag and drop is accomplished simply via PartyKit, based almost exactly on the code in Matt Webb’s mosaic collaborative drawing app. Here you can see how the onDrag coordinates are broadcast to the party via the socket:

// the event source in the inner component
const onDrag = ({ x, y }: { x: number; y: number }, word: Word) => {
  const newWord = { ...word };
  newWord.position = { x, y };
  handleTurn(newWord);
};

// in the page, send the data to PartyKit
const handleTurn = (word: Word) => {
  socket.send(
    JSON.stringify({
      type: "turn",
      word: word,
    })
  );
};

// in the PartyKit server, forward the messages to the rest of the party
const update = <UpdateMessage>{
  type: "update",
  word: msg.word,
  turns: poem.turns,
  players: poem.players,
};
this.party.broadcast(JSON.stringify(update), [connection.id]);

These snippets come from MagenticPoem.tsx, Room.tsx, and partykit/server.ts respectively.

Below the poem area is the save button. Each time you click it, the current state of the poem is first saved to a local Fireproof instance, then replicated to S3, and finally broadcast to all other room members. Among the important details is this insight—the data itself is encrypted end-to-end (even at rest in the browser) and can only be decrypted using a key managed by your PartyKit party. This means you can write the data files virtually anywhere as they are encrypted and self-verifying, so we offer pluggable storage connectors, and will support party-local data in R2 in the near future. Read more about Fireproof connection options here.

The actual code to load the list of saved poems, and to save the poem to the database looks like this (inside the Room component, using Fireproof’s live query React hook). When put is called to save a new poem, useLiveQuery will automatically redraw the list of saved poems in both the local and remote UIs.

const { database, useLiveQuery } = useFireproof("poetry-party");
const savedPoems = useLiveQuery("startedAt", {
  descending: true,
  limit: 50,
}).docs as Poem[];

const handleSave = () => {
  database.put(poem);
};

Sync amongst the party is handled by a simple (less than 30 loc) PartyKit server that you run as a sidecar with your own PartyKit app. You can see how it is configured in the magnetic poetry app here.

Finally, if you click the import button, you’ll be taken to a snapshot of your data in the Fireproof data dashboard. This allows you to view and edit the data, and work with it from other applications. You can also collect data from across multiple apps in your personal dashboard.

To try out the lightweight React Next.js codebase locally, just paste this into your CLI:

git clone https://github.com/partykit/sketch-magnetic-poetry
cd sketch-magnetic-poetry
npm install
cp .env.example .env  # tell the app where to find the partyserver
npx partykit dev  & # background the partyserver
npm run dev       # run the app

Once it’s all running, you can check out the app at: http://localhost:3000/

There’s a tour of the code in the README, so you can easily convert this app into something just your style.

Show us what you got!

SHOW ME WHAT YOU GOT meme

Fireproof is open source (Apache 2.0 & MIT) and ready for your apps. Check out the developer docs and join the GitHub discussions and Fireproof Discord to talk to other builders. Let us know what you build, and we will feature it in our app showcase. We love to share what people do, so tell us about your sketches, demos, games, toys, apps, giant robots, interstellar spacecraft, etc. We hang out in PartyKit’s discord, you can also join the Fireproof discord here!