angularfire: Angular 11 Firebase Server-side rendering infinite loading / pending
Angular: 11
Firebase: 8.2.1
AngularFire: 6.1.4
How to reproduce these conditions
This works as expected in NON-SSR mode, to query once a given collection:
this.firestore.collection<T>('collection', ref => ref.limit(5))
.get()
.pipe(
map((qs: firebase.firestore.QuerySnapshot) => qs.empty ? [] : qs.docs.map(d => d.data() as T)),
);
When switching to SSR, the above code leads to the express server hanging, and the client see a ‘pending’ query that never completes, or hits a timeout and leaves the page partially rendered (i.e. without the results of that query).
This is the best workaround I found:
this.firestore.collection<T>('collection', ref => ref.limit(5))
.valueChanges() <<<<
.pipe(
take(2), <<<<
);
Though this more sane workaround also fails:
this.firestore.collection<T>('collection', ref => ref.limit(5))
.valueChanges()
.pipe(
take(1), <<<<
);
More details about exact version used here: https://stackoverflow.com/questions/65388261/angular-11-firebase-server-side-rendering-infinite-loading-pending/65388376#65388376
Expected behavior
The first version should work without the workaround, without and with SSR.
Actual behavior
Without the workaround, the express server hangs indefinitely.
Related issues: https://github.com/firebase/firebase-js-sdk/issues/3541 https://github.com/firebase/firebase-js-sdk/issues/3542 https://github.com/angular/universal/issues/1711
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 21 (2 by maintainers)
Ran into the same issue. SSR function Timeout on some routes in cloud functions. All pages that triggered a function with a .take(1) operator caused the issue. Changing it to .take(2) solved the problem. Not sure if this should be considered a bug or expected behavior. My thesis: The observable is triggered twice. Once from the SSR, once CSR. Does this make sense?
🚨This doesn’t work:
🥦This works:
Just to bump this topic, I’m experiencing similar issues. I’ve read through all of these threads and tried nearly all of the workarounds suggested. None of them seem to work. I’ve been struggling with this for a couple of weeks.
In my use-case I’m using a resolver to fetch data from firebase before a page load. I’ve noticed very inconsistent results. Occasionally it’ll start working locally - but then the deployed version won’t work.
What’s interesting is the routes don’t hang if I load into the app and then navigate to them; as opposed to linking to them directly. Another thing, it seems like at times the first request to the page I’m attempting to load will work, but then all subsequent requests will fail until I clear my browser cache and try again. Very odd behavior.
Things I’ve tried:
I’m pretty well stuck here. This is pretty frustrating, as I’m maintaining a user-facing app.
If it helps, this is the error I’m seeing in my deployed environment:
Timed out while waiting on cache-bos4679-BOS
hey @jamesdaniels, omg!!! you safe my life!!! thanksssssss!!!
hey @jamesdaniels, thanks for your detailed reply. That makes sense. Not that I understand everything, but it helps a lot. Thanks again, for taking(2) time to reply. ❤️ I will experiment with it and check which is the best recipe for my usecase.
I think that you have to move angular compiled dist inside your functions folder. and deploy all as a function project.
for example: in functions tsconfig.json change da “outDir” from “lib” to “dist” change your ssr function to
` import * as functions from ‘firebase-functions’; const expressApp = require(‘./podcasts11/server/main’).app();
export const server = functions .region(‘us-central1’) .runWith({ timeoutSeconds: 60, memory: ‘1GB’ }) .https.onRequest(expressApp);
`
Move your angular compiled app folder “dist/podcasts11” inside “functions/dist” and your firebase public folder should be “public”: “functions/dist/podcasts11/browser”,
then you can deploy and it will works.
I had this issue months ago and i resolved doing this changes.