Skip to content

Integration with Angular Universal #191

Closed

Description

It just works, except for one thing

WARNING: your application is taking longer than 2000 Zone turns.

(universal-starter)

I guess it is because the connection that angular does with firebase remains open.

On the server, when we are done fetching data from firebase, somehow we need to close the connection, but I don't know if this can be achieved with the current angularfire2 version.

Activity

  1. davideast commented on May 29, 2016

    @davideast
    Collaborator

    I'm not a Universal expert so I'll be summoning @jeffwhelpley.

    Jeff, is there something we need to do to integrate well with Universal?

  2. jeffwhelpley commented on May 30, 2016

    @jeffwhelpley

    Ah, yes. OK, so the short answer here is that we will need to make an adjustment to AngularFire so that (as @mmgdort suspects) the server version must immediately close the connection after getting the initial data set.

    The longer explanation is that on the server side we use zones to wait for all async operations up to 2 seconds. We put in a timeout so that the server code would never hang. So, what I would strongly suggest are the following changes:

    • Automatically close connections after getting initial data
    • No-op calls that are meant for longer time periods
    • You can implement this either through DI swapping (i.e. have a different server version of AngularFire that people import instead of the standard) or monkey patching

    Let me know if you have any questions on this.

  3. doczoidberg commented on Aug 16, 2016

    @doczoidberg

    @mmgdort how do I have to configure Firebase on the server?

  4. msegers commented on Aug 17, 2016

    @msegers

    Heya, as of right now implementing AngularFire2 into my Universal project should just work? Warnings aside of course. "Keeps connection open" does this mean that in the end we'll have a huge memory leak going on or is it only one session which remains active, and is actually a good thing?

    Just interested as I'm implementing AF in a personal universal project

  5. leandroz commented on Sep 23, 2016

    @leandroz

    Any updates on this? Is there a list of things to do where I can help?

    I just started a project with Angular Universal and AngularFire2 so I don't mind investing some time learning the core.

    Aside the initial connection problem, I saw a WindowLocation that is using window.location.

  6. leandroz commented on Sep 23, 2016

    @leandroz

    I am initializing the app in both node and browser modules, which causes this error: Firebase App named '[DEFAULT]' already exists.

    I tried setting different names with the same configurations but the server never responds and hangs indefinitely.

  7. jeffwhelpley commented on Sep 23, 2016

    @jeffwhelpley

    In many cases Firebase is only being used on the client side for realtime data. If that is the case, then you can abstract out your service that references Firebase so it is not used at all on the server side.

    If, however, you are trying to just get that initial snapshot of data from Firebase for your server rendered view, then yes there does need to be some changes. Specifically, I think there are two key pieces to enable this:

    1. Ensure the Firebase libs don't reference any DOM apis and/or provide the appropriate patches so they work on the server side
    2. Add a new zone.js patch that will ensure server rendering will wait until the first Firebase snapshot is complete

    For the second point, basically you need to do something like this:

    https://github.com/angular/zone.js/blob/master/lib/node/node.ts#L65

    That code is used to help Angular Universal keep track of all the http calls on the server and wait for them to complete before returning a rendered page. We need something similar for the Firebase APIs as appropriate.

    @gdi2290 @davideast please weigh in with your two cents.

  8. leandroz commented on Sep 23, 2016

    @leandroz

    @jeffwhelpley thanks for the answer!

    Yes the basic idea is to have the data in the server before doing the first render.

    The firebase lib has a node version so that shouldn't be a problem.
    If Angular Universal is already working with http calls, I can create a parent service and then for the server use a http implementation with the Firebase API directly, and in the browser use Angular
    Fire2.

    How much work would be to create a version of AngularFire2 specific for the server that uses Angular Http service?

  9. jeffwhelpley commented on Sep 23, 2016

    @jeffwhelpley

    If you are doing http to Firebase, then there shouldn't be any issue (let me know if there is). I am guessing that under the scenes Firebase is not using straight http calls, though, because it tries to set up a socket connection, right? So, basically the trick is either just do straight http calls if you run Firebase on the web server for universal rendering (in which case the existing zone.js implementation will work) OR if you use the socket connection, you have to build a new zone.js patch which will wait for the initial snapshot and then automatically close the socket.

    All that said, I haven't tried this out, so there may be other issues I am not thinking about once you get into things. Does that make sense?

  10. leandroz commented on Sep 23, 2016

    @leandroz

    It makes perfect sense, I will try with the http approach and make an update if I found issues!

    Thanks!

  11. orangesoup commented on Sep 24, 2016

    @orangesoup

    @leandroz Please tell us how it goes, I have the same problem, otherwise my app would work. To be honest this feels quite a lot of work to me (at least in my case), so if there is any other approach that would be nice!

  12. katowulf commented on Sep 27, 2016

    @katowulf
    Contributor

    The Firebase web SDK isn't going to work server-side. However, the node.js installation should.

    you can abstract out your service that references Firebase so it is not used at all on the server side.

    Depending on the use case, which I don't really understand, if the SDK is already abstracted, one could just use the Firebase REST API to make static calls. Alternately, simply initializing the node version with a service account on the server would allow the same real-time calls to be used in both.

  13. doczoidberg commented on Oct 11, 2016

    @doczoidberg

    any news on this topic?

  14. tskweres commented on Mar 8, 2017

    @tskweres

    Would love to use AngularFire with Universal, any updates?

  15. samvloeberghs commented on May 9, 2017

    @samvloeberghs

    hi @davideast (@tskweres) I've been upgrading my project to use the latest 4.0.0-rc.0 release.
    Any updates on how to properly stub the AngularFireAuth module for the server module?

    Currently I use the same approach as I did here: angular/universal-starter#127 (comment)
    Some official recommendations might be good ..

  16. ValentinFunk commented on Jul 13, 2017

    @ValentinFunk
    Contributor

    I got it working with universal with a lot of hacking - auth didn't really require any changes, just using Webpack to replace imports to user firebase-node and ignore the angularfire2/* imports. What I had to do is add an endpoint in server to create a custom token from id token and store that as cookie. Server injects REQUEST, reads the cookie and logs into firebase using the custom token.

    For database I needed to patch database.ts and run the call to app.database() in runOutsideAngular(). Then i manually wrap services to create a zoneTask until the first item has been emitted:

    class SomeService {
        getObject(ref) {
            const object$ = this.database.object(ref);
            if (UNIVERSAL) {
                const task = Zone.current.scheduleMacroTask('authService', () => {}, {}, () => {}, () => {});
                object$.first().subscribe(() => task.invoke());
            }
            return object$;
        }
    }

    I haven't used this in a very large app yet so there might be some limitations - but it does work :)

  17. davideast commented on Oct 2, 2017

    @davideast
    Collaborator

    Follow #1073 for the modern version of this issue. There are plans for SSR support, but it's not here just yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions