Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firebase v.9 Firestore getDoc() causes Lighthouse to hang #5398

Closed
maierson opened this issue Aug 27, 2021 · 18 comments
Closed

Firebase v.9 Firestore getDoc() causes Lighthouse to hang #5398

maierson opened this issue Aug 27, 2021 · 18 comments

Comments

@maierson
Copy link

Describe your environment

  • Operating System version: MacOS Big Sur 11.5.2
  • Browser version: Chrome Version 92.0.4515.159 (Official Build) (arm64)
  • Firebase SDK version: 9.0
  • Firebase Product: firstore (auth, database, storage, etc)
  • React / Next.js without SSR

Describe the problem

We are porting our application to v.9 while at the same time attempting to improve the Lighthouse score. When loading a User object from Firestore for the first time we have tried in two ways:

1. gRpc (sdk) installed via npm.

This would be our preferred way to use it for obvious reasons but it appears to hang Lighthouse until it times out. Here is a snapshot of the result:

Screen Shot 2021-08-27 at 5 07 36 PM

  • note that it doesn't affect performance and I can see in the UI that the user data is loaded early on.
  • note the warning at the top "The page loaded too slowly to finish within the time limit". This concerns us in terms of potentially affecting our rankings in a negative way. We are using the following call and have verified that when this is removed everything completes correctly in Lighthouse.
import {doc, getDoc} from "firebase/firestore"

// async setup ...
const userDoc = await getDoc(doc(firestore...))

We are aware of the firestore gRpc bootstrapping initial time but this usually takes about 3 seconds max (plus the user data is already received before that so that's not the issue) and Lighthouse hangs for a lot longer before giving up. It seems as if a connection is not closed properly to allow Lighthouse to complete. Not sure if this is a socket issue - I'm not deeply familiar with the workings of gRpc.

2. REST api with fetch and authentication token.

This call completes in sub-second time and allows Lighthouse to close down without errors.

Steps to reproduce:

Retrieve any document on first page load from Firestore via the getDoc(doc(...)) call.
We have also tried using reactfire but the issue is the same.

@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@dconeybe
Copy link
Contributor

Hello @maierson. Thank you for reporting this issue. Another customer has reported a similar issue (#5402) but I have not been able to reproduce. Are you able to provide an app that I can clone and run for myself to reproduce? If so, that would be incredibly helpful for debugging.

@maierson
Copy link
Author

Hi @dconeybe. Thank you for looking into this.

Here it is: https://github.com/maierson/fbselght

It's built with nrwl / nx which is overkill but I'm trying to get as close as possible to the real app. I've just verified the behavior on Netlify and it's hanging with the regular firebase sdk but not with the /lite one. Same score tests just one never completes.

If you install on Netlify it detects your nrwl project and provides defaults that work out of the box. You just need to set the app name apps/[appName]/out and the environment variables with your firebase project's settings (you can see what they are named in the firebase-config file). This is all under the Site Settings -> Build & Deploy in Netlify.

@maierson
Copy link
Author

I forgot to mention. You'll need an authenticated user in firebase and a users collection in firestore with a user keyed by the auth user's uid (pretty standard). After you login on the first page it sends you to the Main page. This is where the issue happens when it tries to retrieve the user.

@dconeybe
Copy link
Contributor

Thanks for this! I'll be digging into this further tomorrow.

@dconeybe dconeybe added the bug label Aug 31, 2021
@maierson
Copy link
Author

@dconeybe any news on this one? Were you able to reproduce?

@dconeybe
Copy link
Contributor

Ahh yes, my apologies. This bug is almost certainly a duplicate of #5402, which was fixed by #5434. The fix is included in release 9.0.2 (link).

I'm going to close this issue since I believe it to be fixed; however, please feel free to re-open if you disagree or find that the bug persists.

@maierson
Copy link
Author

@dconeybe Thank you for answering. I can confirm that getDoc is resolved with 9.0.2. However collection queries still have this problem. Specifically this type of query:

    const q = query(
      collection(firestore, collectionPath),
      orderBy("dateCreated", "desc"),
    );
    getDocs(q)

This query works when importing from firebase/firestore/lite but hangs in lighthouse when using firebase/firestore. Seems that #5434 only resolved for getDoc but not getDocs. Thoughts?

@maierson
Copy link
Author

Btw I can't reopen this issue once you've closed it. Can you please reopen it?

@dconeybe
Copy link
Contributor

Reopening since getDocs() seems to be affected by the same issue and needs to be fixed.

@dconeybe dconeybe reopened this Sep 13, 2021
@schmidt-sebastian
Copy link
Contributor

@maierson Can you share your debug logs? I am not able to reproduce the described behavior with either getDoc or getDocs even when using your repro:

getDoc:

FirebaseCredentialsProvider Auth detected
FirestoreClient Received user= HLUY8LkivwPTmcosPgPPOZ78lQD3
FirestoreClient Using default OnlineComponentProvider
FirestoreClient Using default OfflineComponentProvider
FirestoreClient Initializing OfflineComponentProvider
FirestoreClient Initializing OnlineComponentProvider
MemoryPersistence Starting transaction: Allocate target
MemoryPersistence Starting transaction: Execute query
QueryEngine Using full collection scan to execute query: Query(target=Target(users/HLUY8LkivwPTmcosPgPPOZ78lQD3, orderBy: [__name__ (asc)]); limitType=F)
Connection Creating WebChannel: https://firestore.googleapis.com/google.firestore.v1.Firestore/Listen/channel {...}
Connection Opening WebChannel transport.
Connection WebChannel sending: {"database":"projects/.../databases/(default)","addTarget":{"documents":{"documents":["projects/.../databases/(default)/documents/users/HLUY8LkivwPTmcosPgPPOZ78lQD3"]},"targetId":2}}
Connection WebChannel transport opened.
Connection WebChannel received: {"targetChange":{"targetChangeType":"ADD","targetIds":[2]}}
Connection WebChannel received: {"documentDelete":{"document":"projects/.../databases/(default)/documents/users/HLUY8LkivwPTmcosPgPPOZ78lQD3","readTime":"2021-09-13T15:39:40.044908Z","removedTargetIds":[2]}}
Connection WebChannel received: {"targetChange":{"targetChangeType":"CURRENT","targetIds":[2],"resumeToken":"CgkI7KzFr6T88gI=","readTime":"2021-09-13T15:39:40.044908Z"}}
Connection WebChannel received: {"targetChange":{"resumeToken":"CgkI7KzFr6T88gI=","readTime":"2021-09-13T15:39:40.044908Z"}}
MemoryPersistence Starting transaction: Get last remote snapshot version
MemoryPersistence Starting transaction: Apply remote event
MemoryPersistence Starting transaction: notifyLocalViewChanges
MemoryPersistence Starting transaction: Release target
Connection WebChannel sending: {"database":"projects/.../databases/(default)","removeTarget":2}
Connection WebChannel received: {"targetChange":{"targetChangeType":"REMOVE","targetIds":[2]}}

'getDocs' shows similar logs for me.

@maierson
Copy link
Author

@schmidt-sebastian I have no meaningful logs because this is in production mode on netlify. Some pointers: get doc seems to have been solved in 9.0.2, it's only getDocs that hangs Lighthouse for me in the same exact way that getDoc used to. One thing to look into the repro is this firebase-client file: https://github.com/maierson/fbselght/blob/main/apps/test/util/firebase-client.ts
When I use the lite version of firebase/firestore/lite all is ok but when i use firebase/firestore it hangs. This is in our production app so cannot share the full code but I've isolated it to the query above.

I don't have it implemented in the repro but will try to do it once I have a moment to confirm.

@schmidt-sebastian
Copy link
Contributor

schmidt-sebastian commented Sep 13, 2021

I see the same behavior for getDoc/getDocs (when I filter for a single doc in getDoc). Lighthouse passes for me, but it is a bit slow. When I open the console logs for Lighthouse I see that the documents are fetched right away, but Lighthouse continues its measurement.

I am not able to make much progress here. If you think it might be worthwhile to talk this over, shoot me an email to mrschmidt(at)google.com.

@maierson
Copy link
Author

Yes correct. That's what I see too: docs load quickly but Lighthouse completes quite a lot later with the warning that the page loaded too slowly to finish within the allotted time. If I use the lite version it completes right away.

It used to do that for getDoc before 9.0.2 but that was fixed. Now it only does it for getDocs. I'll update the repro to make sure there's nothing else affecting it in the production app that I've been testing with and will revert.

@LizAinslie
Copy link

I'm still experiencing this behavior in v9.8.4. Someone in #5402 mentioned that this possibly caused by where the auth persistence is placed, but there isn't much I can do about that unfortunately, as below is my initialization and persistence code in verbatim with options omitted.

window.firebaseApp = initializeApp({ ... });
await getAuth(window.firebaseApp).setPersistence(browserLocalPersistence);

I'm also able to log the uid in the code where I'm experiencing the block:

export async function fetchProfile(uid: string): Promise<Profile | undefined> {
    console.log('[fetchProfile]', uid);
    const firestore = getFirestore(window.firebaseApp);
    const cacheStore = useCacheStore();

    const profileFromCache: IProfile | undefined = cacheStore.profileCache[uid];
    console.log('[fetchProfile]', 'cache', profileFromCache);
    if (!!profileFromCache) return new Profile(profileFromCache);
    else {
        console.log('[fetchProfile]', 'using firestore');
        const docRef = doc(firestore, `/users/${uid}`) as DocumentReference<IProfile>
        console.log('[fetchProfile]', 'ref', docRef);
        const docSnap = await getDoc(docRef);
        console.log('[fetchProfile]', 'snap', docSnap);
        console.log('[fetchProfile]', 'snapExists', docSnap.exists());
        const profileFromFirestore = docSnap.data();
        console.log('[fetchProfile]', 'firestore', profileFromFirestore);
        if (!!profileFromFirestore) return new Profile(profileFromFirestore);
        else return undefined;
    }
}

Here's a screenshot of the console output for that code:
Screenshot

Someone else on the #5402 thread mentioned this Rollup issue which also might be to blame since I'm currently using Vite and TS, though I'm not entirely sure of the relevance.

Either way, any help would be greatly appreciated, cheers!

@milaGGL
Copy link
Contributor

milaGGL commented Dec 15, 2023

I am able to reproduce the "The page loaded too slowly to finish within the time limit" warning message in lighthouse. Lighthouse is waiting for the watch stream to close, while the SDK keep it open for new requests that might come in. This should not affect web performance, as you noticed, the expected data has been received promptly.

However, I am unable to reproduce the unresponsive getDoc or getDocs, even when using authentication and persistence. Is there any repro steps I can try?

@google-oss-bot
Copy link
Contributor

Hey @maierson. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@google-oss-bot
Copy link
Contributor

Since there haven't been any recent updates here, I am going to close this issue.

@maierson if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

@firebase firebase locked and limited conversation to collaborators Jan 29, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants