question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Route freezes with Resolver getting data from Firestore in SSR

See original GitHub issue

Version info

Angular: 11.0.2

Firebase: 8.1.1

AngularFire: 6.1.2

Other (e.g. Ionic/Cordova, Node, browser, operating system): Chrome 87, Windows 10, Angular Universal, Node 12.14.1

How to reproduce these conditions

  1. Create Angular Universal app with Firebase
  2. Add Resolver that fetches data from Firestore to a lazy route
  3. Try navigating to that route in SSR
    resolve({params}: ActivatedRouteSnapshot): Observable<any> {
        console.log('Resolver');

        return this.firestore
            .doc(params['id'])
            .get()
            .pipe(
                tap(() => console.log('Resolved')),
                catchError(() => this.router.navigate(['']) && EMPTY),
            );
    }

I also added console.log('Constructor') in that route’s component constructor.

Debug output

Console logs print out correctly:

Resolver
Resolved
Constructor

Expected behavior

Route opens with resolved data

Actual behavior

Route is stuck on loading, server does not return the page

Here comes the weird part

There’s a very strange way to kick-start it 😃

  1. Replace doc with collection in Resolver
  2. Add some other request to Firestore in route’s component (doesn’t matter doc or collection)
  3. Use async pipe in template to show that new request’s result

I’m very confused.

It’s hard to provide a reproduction, because it’s SSR. I’ll be happy to show it in my app if somebody is willing to live chat, it’s pretty straightforward.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:9
  • Comments:15 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
inorganikcommented, Jan 5, 2021

@Marcusg62, I was able to make your app serve the route from SSR - the issue is that you have several subscriptions and an angularfire auth subscription in your orderForm service, which is injected in your component. The auth subscription will never complete, and the other subscriptions don’t either.

Instead of using the behavior subject in your service, refactor it so that there are no subscriptions in it, and pass your Restaurant to your initializeOrderObject() method. Only init the formGroup once and then use patchValue() on it in your initializeOrderObject method. Services have no lifecycle hooks so you can’t control subscriptions.

Here’s how you can make it serve the restaurant route (you will need to later inject the service again after you remove all the subscriptions in it):

component:

@Component({
  selector: 'app-restaurant',
  templateUrl: './restaurant.component.html',
  styleUrls: ['./restaurant.component.scss']
})
export class RestaurantComponent implements OnInit {
  restaurant: Observable<Restaurant>;

  constructor(
    private route: ActivatedRoute,
    public afs: AngularFirestore
  ) {}

  ngOnInit(): void {
    const path = this.route.snapshot.url[1].path;
    this.restaurant = this.afs.doc<Restaurant>('restaurants/' + path).valueChanges();
  }

}

template:

<div class="bg" *ngIf="(r | async) as r2">
  <!-- this just shows raw data, but it proves you can server-side render the route -->
  {{ r2 | json }}
</div>
2reactions
Marcusg62commented, Dec 24, 2020

I am having the same issue. I have tried using promises as a workaround but no luck. Here is a link to my github repo with the bug. The route resolver is in src/app/resolvers/restaurant.resolver.ts

The problem is with ssr, so just npm i and npm run dev:ssr Then copy paste this to your browser bar localhost:4200/restaurant/bistroKing

The behavior is exactly as @waterplea describes, you go to the specific route (to be sure it uses SSR), and the browser just spins with no timeout. I don’t know why, but sometimes if you click into the bar again and hit enter while it was previously loading, it will then work without problem. See video:

https://user-images.githubusercontent.com/21998115/103108236-300df780-4603-11eb-920f-a11b83d2ab49.mov

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular universal: Route resolver + Firebase loading timeout
This code works fine but stops working when a page is being refreshed or navigated to directly when being served with SSR using...
Read more >
A brand new website interface for an even better experience!
Route freezes with Resolver getting data from Firestore in SSR.
Read more >
Best practices for Cloud Firestore - Firebase
The Cloud Firestore SDKs and client libraries automatically retry failed transactions to deal with transient errors. If your application accesses Cloud ...
Read more >
Resolver Not Returning Firestore'S Data To Load A ...
Route freezes with Resolver getting data from Firestore in SSR #2695 Route is stuck on loading server does not return the page. Fetching...
Read more >
[Solved]-Getting UID Reference for Firestore-angular.js
db.collection(collection).doc(uid).set(data);. The other is adding the thocument but letting firestore generate the uid for you. db.collection( ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found