firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.86k stars 894 forks source link

FR: Add Create Bundles Support #8354

Open jdgamble555 opened 4 months ago

jdgamble555 commented 4 months ago

Operating System

n/a

Browser Version

n/a

Firebase SDK Version

10.12.3

Firebase SDK Product:

Firestore

Describe your project's tooling

Web Frameworks with SSR.

Describe the problem

Before FirebaseServerApp was released, you had to use firebase-admin-node on the server. When the data gets hydrated, you would fetch the data twice.

However, since firebase-admin has bundle support, you can fetch the data on the server, and load the data to the cache on the browser using:

await loadBundle(bundle);

However, Firebase JS SDK doesn't have a way to create the bundle. Here is an example:

export const getTodos = async (uid: string) => {

    let todoSnapshot: QuerySnap;

    try {
        todoSnapshot = await adminDB
            .collection('todos')
            .where('uid', '==', uid)
            .orderBy('createdAt')
            .get();

    } catch (e) {
        const fb = e as FirebaseError;
        error(500, fb.message);
    }

    const bundleId = Date.now().toString();

    // create buffer as string to pass to client
    const todoBuffer = adminDB
        .bundle(bundleId)
        .add('todo-query', todoSnapshot)
        .build()
        .toString();

    const todos = snapToData(todoSnapshot);

    // Here, the todoBuffer is the bundle to be loaded later
    return { todos, todoBuffer };
}

There should be a way to either:

  1. Create the bundle on the server like firebase-admin-node
  2. Pass the data to the browser to be hydrated preventing you from double fetching

Both of these options would allow caching through a CDN.

Steps and code to reproduce issue

Currently there are no work arounds without using REST API or firebase-admin-node.

The client side is already working with loadBunde(), just need a way to create the bundle on the server.

J

wu-hui commented 4 months ago

I am not very familiar with SSR, one question I have: other than being more convenient and less dependency, there is no advantage to have the Web SDK building the bundles, is that right?

In fact, building bundles with Web SDK has more performance issue because of how web sdk executes in a sequential manner, which means more latency will be introduced to the App.

I am not against adding this feature, if it does have a significant benefit for SSR usage.

jdgamble555 commented 4 months ago

I am not very familiar with SSR, one question I have: other than being more convenient and less dependency, there is no advantage to have the Web SDK building the bundles, is that right?

No that is incorrect. There is one huge advantage. You need to be able to load data into the Firestore cache so that there is not an extra read.

This SDK uses loadBundle() to load the bundle into the SDK so that you don't have to refetch from the server 2x. This is important for promise fetching, and more important for websocket fetching. It won't have to refetch the data on the client that has already been fetched on the server.

J

wu-hui commented 4 months ago

Thanks. I think this is a legit feature request and I have added to our task queue to research on how to better support SSR. Unfortunately we cannot give any timeline at this time.

Internal tracking bug for googlers: b/352088326