angularfire: "Unexpected token import" with angularfire2 on angular-cli, AOT, SSR, and firebase-functions
Has anyone done this? I’m stuck, would love some suggestions, or pointers if I’m missing something obvious or misunderstanding the problem.
Version info
Angular: 4.2.4
Firebase: 4.1.3
AngularFire: 4.0.0-rc1
Firebase-functions: 0.5.9
How to reproduce these conditions
Using AOT compiling, and server-side rendering, as described in this blagpost: https://medium.com/@evertonrobertoauler/angular-4-universal-app-with-angular-cli-db8b53bba07d
Repo:
https://github.com/SparksNetwork/exp-angular-firebase/tree/shared-code
(note I am working from the shared-code
branch)
(the repo structure is kind of haphazard, everything lives in /functions
because thats what firebase-functions requires)
Steps to set up and reproduce
App runs successfully JIT running ng serve
.
Compile client and server with ng run build
.
Serve via standalone node express server with ts-node src/server.ts
or via firebase-functions local emulator with firebase serve --only functions
.
Debug output
FirebaseError: Error occurred while parsing your function triggers.
/Users/sdebaun/exp-angular-firebase/functions/node_modules/angularfire2/app/firebase.app.module.js:1
(function (exports, require, module, __filename, __dirname) { import { InjectionToken, } from '@angular/core';
^^^^^^
SyntaxError: Unexpected token import
at createScript (vm.js:53:10)
at Object.runInThisContext (vm.js:95:10)
at Module._compile (module.js:543:28)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/Users/sdebaun/exp-angular-firebase/functions/fn/dist/dist/ngfactory/src/app/app.server.module.ngfactory.js:23:13)
i functions: No HTTPS functions emulated. Support for other function types are coming soon.
Diagnosis
I suspect it’s choking because the angularfire2 npm module is compiled with es2015 syntax which doesn’t work in node (which firebase-functions is based on).
Possible fix?
I don’t know a lot about how NPM works, but I’m wondering if I:
- Fork angularfire2
- change the
target
and/ormodule
settings in forked tsconfig until I find something that works - in my app,
npm install
from my forked angularfire2
Only thing I don’t know how to do there is: how do I ensure that my forked angularfire2 gets built? There’s a bunch of stuff in the repo that has to do with the build process that is totally alien to me.
The only other thing I can think of is to try to write my own firebase wrapper for angular, with blackjack and hookers that compiles to commonjs. That sounds like an awful idea.
Things I’ve Tried
Using DI to swap out AngularFire2 on server
Per the discussion in this thread (https://github.com/angular/universal-starter/issues/127#issuecomment-287644140), I started writing a fake service that adhered to the angularfire2 interfaces that I could use in my app.server.module.ts. Quickly I realized that because all my services actually have to import from the real angularfire2 module, it still wouldn’t work, because the error gets thrown when the file is imported, not when it’s run.
Copying angularfire2/src into a local lib directory and building it with the project
When I try this, I get all sorts of errors about Zone not being found. I can’t figure out what needs to be included, or how, in order to get it to compile the ts.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 1
- Comments: 40 (12 by maintainers)
Finally Server Side Rendering with Firebase 😊
🎉 Introducing AngularFire Lite 🎉
AnglularFire Lite is a very very simple library to use Angular with Firebase it supports server-side rendering out of the box for both firebase realtime database and firestore. It renders the SSR app and then switches to the non-SSR to receive real-time updates from firebase with no flickering at all when the angular app bootstraps. Visit AngularFire Lite repo to get started today:
Get Started
Demo App
Please note that this is a personal initiative I started and it’s still in very early beta so your help by contributing and supporting the library will be the only way to improve it.
@hamedbaatour This is really cool! I wish you would have contributed to this project however. We plan on adding support for the rest of the Firebase features soon.
I do have one question, is it actually lighter than AngularFire? AngularFire itself is really small, the DB API is 3kb. The Firestore API is 2.3kb. The Auth API is 950 bytes.
@justingrayston @sdebaun I’m close to a
next
release for this fix. If all goes well I’ll be testing an Angular Universal build with the CLI. I’ll keep you updated.@sdebaun I recently ran into this myself. I have a fix in the works but I just moved halfway across the country so my schedule is pretty jammed right now. I do expect to get something out next week.
There’s a big overhaul needed in how we package these modules. We need a UMD bundle for each feature (auth, db) rather than one larger one. I’m looking into mimicking the structure that the main Angular repo uses with their package.json and tsconfig.files. A good example is with the HTTP module.
“angularfire2”: “^5.0.0-rc.6” seems to be working with ssr. Did anything change ?
I tried to do SSR on Cloud functions with AngularFire2 included. There are no errors and data is fetched from RTDB as it can be seen printed in to the logs. But the html pages never render and soon timeout. @davideast Any updates on the possible fix you mentioned?
@sdebaun @justingrayston @KrGyan
Yes and no. Mostly no. #1088 fixed the problem that @sdebaun ran into. The Angular Compiler used deep imports to import the feature modules, when I needed to use the UMD bundle. I spent a lot of time getting the packaging of each module correct.
Now, if you use AngularFire2 with Angular Universal, there will be no errors*. However, the data will not render on the server. You’ll get back
null
in your templates. This is because AngularFire2 uses the Firebase SDK which uses websockets. Websockets are long-lived persistent connections. Angular Universal doesn’t know when this socket will end. I can fix this by wrapping the calls for Universal, but that will be another PR. I plan on working on that next week.*i think
@ncherian @paulogr so the main problem is actually not the socket, but Zone.js, we have a bug in our handling. The microtasks are never allowing appRef isStable to go true, thus Universal never letting go of the rendering until Timeout and even once you do have a rendered page state restoration never happens.
If you wrap in a zone.runOutsideAngular() things work. I have on my list to fix.
I fixed a similar problem in @ngx-translate/core. Please take a look to my comment here. or even better the full explanation i did it locally too for the angularfire2 module.
I used the cli of babel to compile all js file into es5 - commonjs so that i can use them in nodejs (express) with angular universal --> finally no more SyntaxError: Unexpected token import!
There’s also no node.js entry to
firebase/app
which is a bug + why Websockets aren’t getting pulled in.(global as any).WebSocket = require("ws");
in your server.ts works until I get that patched upstream 😉I was able to resolve the usage of angularfire2 on server side creating and injecting a “stub” version of AngularFireDatabase that uses the firebase rest api. As @davideast said the problem of timeouts or never render templates is the websocket that never finish and angular do not knows when finish rendering.
I didn’t even include the angularfire modules on server side.
Hope it helps.
I have Firebase Auth “working” in my starter project here:
code: https://github.com/patrickmichalina/fusebox-angular-universal-starter demo: https://angular.patrickmichalina.com/login
@doczoidberg there’s a pull request (#1454) for that, so probably soon 😃
still looking forward to make my web go production 👍 , event I have dedicated server, when calling to firebase, my data still not render with universal. I can’t SEO
Looking forward to SSR support
wow, you deserve this 🥇 I love that, finally, I can’t wait to use this, thanks you for your initiative. That help me a lot and make my dream come true. I still didn’t using any different database to only work with firebase
Have same problem here, html pages never render when using AngularFire. @davideast any update?
Got around the problem by providing firebase-admin to a FirebaseAdminService, then using that instead of Angularfire2 in a ServerDatabaseModule. Sorry, not a complete example but hope this gives you ideas:
https://gist.github.com/funkizer/6d6559787c17a88c60cf2ddc9ca06527 https://gist.github.com/funkizer/e162adff4191cae3c897e6bc5b7fd605
If you’re hosting Universal on your own server, you might get away with not getting rid of all Angularfire2 stuff, but at least on Cloud Functions, you’ll get ctor is not a constructor or other funny errors or timeouts because injectors fail, so I just got rid of everything related to FB client on server. Key thing is to run firebase-admin related things wrapped in zone.runOutsideAngular().
@justingrayston my workaround was… disable SSR until the fix is posted 😃