Skip to content

Requesting data with source: server does not actually go to server and returns data from cache  #7848

Closed
@andreymikhadyuk

Description

@andreymikhadyuk

Operating System

Windows 11 Pro 22H2

Browser Version

Firefox v120.0.1 (64-bit)

Firebase SDK Version

^8.3.2

Firebase SDK Product:

Firestore

Describe your project's tooling

It is web app written using React v17.0.1. For state management we use redux (with sagas).

Describe the problem

We've enabled persistence in our app. In some places we rely on the cached data. So sometimes we do request using source: cache and if there is no data in cache we try same request using source: server.

We display a list of items and for each item we fetch its discussion. The issue is that for one of our teammates somehow after some time of app usage some discussions become empty in the cache, but even doing a request with source: server does not really go to server, we still get empty data in the response (and yes, by the query we have data in the db). In another browser or after clearing the cache the issue is solved. Changing cache size to unlimited did not solve the problem.

Me and my teammate tried to intentionally reproduce the issue by doing following:

  • we tried to limit the cache size to 1 Mb and play with the app. We tried to reach some cache clearings by garbage collector and everything worked fine, we could not get the state when we see incorrect data (I tested in Chrome (119.0.6045.159) and Firefox (120.0.1) on my MacBook (macOS 13.4.1));
  • going offline with source: server did not throw an error. The code continued working in the try block and in the logs we could see null data having fromCache=false.

So we could not reproduce the issue. But my teammate has this issue in our dev and prod environments in his Firefox.

Steps and code to reproduce issue

As I mentioned in the problem description, we could not intentionally reproduce it.
Here is the code example of how we fetch that data:

const getDiscussionById = async (
  discussionId: string,
  source: "default" | "server" | "cache" = "default",
): Promise<Discussion | null> => {
  try {
    const snapshot = await firebase
      .firestore()
      .collection("discussion")
      .withConverter(converter)
      .doc(discussionId)
      .get({ source });
    const discussion = snapshot.data() || null;

    if (!discussion && source === "cache") {
      return getDiscussionById(discussionId, "server");
    }

    return discussion;
  } catch (error) {
    if (source === "cache" && isFirestoreCacheError(error)) {
      return getDiscussionById(discussionId, "server");
    } else {
      throw error;
    }
  }
};

We tried to remove the logic of fetching with source: cache by using just source: server to get data directly from server, but we still get empty data having fromCache=false. As I mentioned in the problem description, going offline does not throw the error during the request, the code keeps executing in the try block with empty data in the snapshot.data().

const getDiscussionById = async (
  discussionId: string,
): Promise<Discussion | null> => {
  const snapshot = await firebase
    .firestore()
    .collection("discussion")
    .withConverter(converter)
    .doc(discussionId)
    .get({ source: "server" });
  const discussion = snapshot.data() || null;

  return discussion;
};

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions