angularfire: Release Candidate API proposal! Breaking changes please read!
Release Candidate API Proposal
Please read and leave feedback!
AngularFire2 is almost ready for its first semver release! Before that can happen, a few problems must be addressed.
Removing AngularFire
for Modularity
AngularFire2 does not take advantage of the Firebase SDK’s modularity. Users who only need authentication receive database code and vice versa. The AngularFire
service is a central part of this problem. The class includes each feature whether you are using it or not. Even worse, this cannot be tree-shaken. As the library grows to include more features, this will only become more of a problem.
The way to fix this is to remove the AngularFire
service and break up the library into smaller @NgModule
s.
AngularFireModule
(Firebase app only)AngularFireAuthModule
AngularFireDatabaseModule
AngularFireStorageModule
(Future release)AngularFireMessagingModule
(Future release)
This will allow you to get the code for only what features you need. Below is an example setup:
import { NgModule, Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule, AngularFireDatabase } from 'angularfire2/database';
import { AngularFireAuthModule, AngularFireAuth } from 'angularfire2/auth';
const config = { }; // firebase config
@NgModule({
declarations: [ App ],
exports: [ App ],
imports: [
AngularFireModule.initializeApp(config)
AngularFireDatabaseModule,
AngularFireAuthModule,
],
bootstrap[ App ]
})
export class MyModule { }
@Component({
selector: 'my-app',
template: `
<div> {{ (items | async)? | json }} </div>
<div> {{ user.authState | async)? | json }} </div>
`
})
export class App {
user: Observable<any>;
items: Observable<any>;
constructor(auth: AngularFireAuth, db: AngularFireDatabase) {
this.items = db.list('items');
}
}
Instead of pulling each feature off the AngularFire
service, you now import each feature module.
Breaking: Simplified Authentication API
The goal of AngularFire (1 & 2) is not to wrap the Firebase SDK. This is something I wrote in a blog post way back in 2014 about AngularFire 0.8.
The goal is to provide Angular-specific functionality. We’ve done this with FirebaseListObservable
and its advanced querying techniques, but the current authentication API offers little outside of the Firebase SDK. The Authentication API also requires the most maintenance as it has quirks across different browsers and platforms like Cordova. Wrapping the API puts AngularFire2 in the middle of these changes, make it prone to break.
My solution is to simplify the API. This, however, means breaking changes. Below is the proposed API and an example:
interface AngularFireAuth {
auth: FirebaseAuth;
authState: Observable<firebase.User>;
}
import { NgModule, Component } from '@angular/angularfire2';
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuthModule, AngularFireAuth } from 'angularfire2/auth';
const config = {}; // firebase config
@NgModule({
declarations: [ App ],
exports: [ App ],
imports: [
AngularFireModule.initializeApp(config)
AngularFireAuthModule,
],
bootstrap[ App ]
})
export class MyModule { }
@Component({
selector: 'my-app',
template: ` `
})
export class App {
constructor(private afAuth: AngularFireAuth) {
afAuth.authState.subscribe(user => console.log(user));
}
signIn() {
afAuth.auth.signInAnonymously();
}
}
The authState
observable is the best candidate for Angular-specific functionality. The rest of the methods are removed.
This proposal removes custom methods like .createUser()
. Most of the custom authentication methods were simply wrapper calls around the official SDK. Rather than creating more bytes for no value, the Firebase Auth instance is available as a property named auth
where the same functionality exists.
Remove pre-configure login
This change also removes pre-configuring login. Pre-configuring is a convenient feature, but this API has introduced a fair amount of complexity into the codebase for fairly low value. This is another decision to forgo minor conveniences for simplicity and less code.
I understand that this is likely the hardest of all the breaking changes, so I am open to suggestions. However, I want to keep to the ideals that AngularFire2 is not a wrapper.
We also have plans for authentication based route guards, but more research is needed before we have an API.
Breaking: FirebaseListFactory and FirebaseObjectFactory only take in a Database Reference
This change only affects a few users who directly use FirebaseListFactory
. Most people inject AngularFireDatabase
directly or use the AngularFire
service.
If you directly use FirebaseListFactory
you will no longer be able to pass in a string. **The AngularFireDatabase
service will still take paths for .list()
and .object()
. With the FirebaseApp now easily injectable, you can create a reference while still adhering to DI.
This is a minor change, but again it prioritizes simplicity. It keeps the library from writing check logic at multiple abstractions. This again reduces complexity and maintenance.
Below is an example:
import { FirebaseApp } from 'angularfire2';
import { FirebaseListFactory, FirebaseObjectFactory, AngularFireDatabase } from 'angularfire2/database';
@Component({
selector: 'app',
template: ``
})
export class App {
list: Observable<any>;
constructor(app: FirebaseApp, db: AngularFireDatabase) {
const listRef = app.database.ref('things');
const list = FirebaseListFactory(listRef);
const obj = FirebaseObjectFactory(listRef.child('thing_1'));
// const list = FirebaseListFactory('things'); <- no longer valid
// const obj = FirebaseObjectFactory('things/thing_1'); <- no longer valid
const list2 = db.list('things'); // still valid
const obj2 = db.object('things/thing_1'); // still valid
}
}
Semver: AngularFire2 4.0
Let’s talk about naming. AngularFire2 is the second AngularFire. It’s not “AngularFire” for Angular 2. Now, I’ll admit, this isn’t ideal for a name. However, we can’t rename the original AngularFire to AngularFireJS. There are many people with AngularFire apps in production and we do not have to cause a problem over vanity.
When we release the semver version will be AngularFire2 4.0.
When the breaking changes are implemented, AngularFire2 will enter version rc0
. Once enough adoption and feedback have been received (and bugs fixed), will release to 4.0.
We are investigating scoped packaging to get @angularfire/core
, @angularfire/database
, @angularfire/auth
, and etc. However, there are draw backs to maintaining several scoped packages, such as handling several version mismatches.
Post 4.0
After 4.0 we’ll focus on features. Here are the items on the docket:
- Cloud Storage for Firebase (with a snazzy directive too!)
- Firebase Cloud Messaging
- Authentication Route Guards
- A real documentation site
- Lazy loading of Firebase Feature Modules (independent of router)
- Angular Universal Integration
Conclusion: Sticking to a principle
This is a big change. But this change brings several new benefits, and most importantly a guiding principle for AngularFire2. AngularFire2 is not a wrapper around the Firebase SDK. AngularFire2 integrates Firebase into Angular-specific features. If the solution is a simple function wrap, then it doesn’t fit the principle.
Your feedback is not only welcome, but it is necessary in making AngularFire2 the best Firebase and Angular experience possible.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 64
- Comments: 47 (19 by maintainers)
Commits related to this issue
- Temporarily use popup instead of redirect auth Redirect was only sending the user:email scope to GitHub even when requesting repo. As per https://github.com/angular/angularfire2/issues/798 this does ... — committed to DarranShepherd/githyde by DarranShepherd 7 years ago
- Add information about individual @NgModules Copied some material from https://github.com/angular/angularfire2/issues/854 into this doc — committed to fisherds/angularfire2 by fisherds 7 years ago
- Add information about individual @NgModules (#942) * Add information about individual @NgModules Copied some material from https://github.com/angular/angularfire2/issues/854 into this doc * add... — committed to angular/angularfire by fisherds 7 years ago
- Add information about individual @NgModules (#942) * Add information about individual @NgModules Copied some material from https://github.com/angular/angularfire2/issues/854 into this doc * add... — committed to starglow-ventures/Angular-Firebase by fisherds 7 years ago
- Add information about individual @NgModules (#942) * Add information about individual @NgModules Copied some material from https://github.com/angular/angularfire2/issues/854 into this doc * add... — committed to noproblem23/angularfire by noproblem23 7 years ago
#itJustAngularFire 😃
But seriously: I love the focus on the code size and modularity. I think this is awesome.
What I don’t see, is discussion about TypeScript version used to produce the
d.ts
files and strictNullChecks compatibility. If you are going to cut a major release, then I’d recommend you drop support for older TS and jump on TS 2.2 and make your api surface strictNullChecks compatible.PS: if you are going break all this stuff, please make sure you document the migration path. These changes while painful are very much necessary, and having good documentation makes the pain hurt less.
PS2: if you are going to break all this stuff, then just rename the thing to
angularfire
v4.0.0 (drop the “2”). Use version numbers to communicate the difference between v1, v2 and v4. Anything else is very confusing to anyone not closely following the development of the library.@elekzalan @myspivey The first
next
release is available for testing and it supports Angular 4.npm i angularfire2@next --save
It has been merged and released!
I like the idea of breaking up AngularFire2 into smaller modules. The breaking changes do not seem to be like they will be much of a pain as long as you have clear documentation. I think many of us are only Injecting Auth and Database in our services. Removing some of the wrapper functions are also a great idea, it’ll force us to learn more from the SDK itself, which is necessary to get a complete user experience.
What I’m really looking forward to is the documentation, specifically best practices. I’d love us to have somewhere to talk about and share exactly how we’re using AngularFire2 in order to help develop those practices. It would be nice to get to a point where some of us are sharing modules that we can drop into our projects and build upon. Are you using stores? How are you building them to work with AF? (Just a couple rhetorical questions)
I like this!
Modularity is key and will be a huge improvement in reducing bundle sizes and boot times. Just that is already worth as many breaking changes as needed.
Agreed. The least the library does, the better. If it’s not specific to Angular then it should be done directly via the SDK or through some other library.
About auth, not much to add. Besides wrapping auth state changes in an observable, everything else can be done directly on the SDK. Just some bikesheding:
afAuth.authState
->afAuth.state
.About versioning:
Does that mean maintaining version parity with Angular in the future? Because that wouldn’t really be using semver, if AF bumps minor version without any new features, or major versions without actually introducing any breaking changes. If parity is not the goal here, then AngularFire2 3.0 might be more appropriate (I know, I know… more bikeshedding).
As for all the new features planned for the future: yes please, but only if they make sense in an Angular environment. About “Authentication Route Guards”: OMG YES.
Last ~but not least~ and absolutely least, just an idea: since AF will be split into separate modules, how about publishing them as separate packages instead of as one?
So instead of having just the
angularfire2
package and do naked imports from inside it:We could have separate packages for each functionality like
@angularfire/app
,@angularfire/auth
, and@angularfire/database
like this:Also… two birds, one stone, right? 😉
Just migrated my app (auth + database) and it works like a charm! Well done! I was a bit behind with my firebase dependency (3.5 ish) so had to fix some api changes for auth but it was easily fixed
I like the idea of less code in angularfire2, just to make it easier to follow along with firebase releases, and their docs are a lot more comprehensive than yours.
I do not like the idea of jumping to 4.0 if you’re not going to keep version parity with angular. And I don’t feel like keeping version parity with angular would give much of a benefit, but it doesn’t really matter all too much in the end.
I also think that putting angularfire2 in either
@angular/firebase
or@angularfire
is the best solution. Leaving the 2 in the name will just cause confusion later on.Compare to @angular/material, their naming/packaging scheme makes perfect sense.
@albanx If you want an observable that emits a
boolean
indicating whether or not there is a connection, you can use Firebase’s.info
:I don’t think there’s much to be gained by wrapping anything around that.
@davideast I’m curious as to what the potential problems are with the scoped names. I think that using the
@angularfire
scope would be the most straightforward way of getting the2
out of the name.Hopefully, using multiple, scoped packages won’t impose too much of an administrative burden.
@exxmen you need to import:
inside your module, for instance, app.module.ts
@martzcodes @Maistho Make sure to only import the typings since you have already configured AF auth in your NgModule.
I don’t think we plan on adding providers to AF as that would provide a duplication between the auth library and AngularFire. I plan to add a documentation section on how to use the SDK with AF that will hopefully clear this up.
Tried migration my smallish app that uses db and Auth, and apart from spending some time reworking the Authentication (it’s much easier to link accounts now) it was completely painless. Looking great!
@davideast @cartant creating several packages (scoped or not) from a single repo is quite easy using a tool like Lerna. I just went through that process myself and it’s straightforward to set up. Those who advised against it, did they give any specific reasons? I’m actually quite interested here.
Just because I gave this some more thought, I’ll reiterate: don’t jumpt to v4. I think the best course of action would be to:
@angularfire/*
packages) is compatible with the latest version of Angular. No need to mention version numbers, and the message is clear.authState
is fine. My main issue with it was thatafAuth.authState
sounds kind of redundant, but it’s true that by itselfauthState
is much more clear thanstate
, which might be too vague.I’m conflicted about AngularFire exposing the child added/removed/etc as observables. On one hand that’s something I always end up doing myself whenever working with Firebase and RxJS so I see some merit as to why it’d be useful to have, but that’s not something you might consume directly on the template to update the UI. So this wouldn’t really be about Angular but just about providing handy observables to the underlying SDK events, and isn’t that the kind of approach the new API is trying to get rid of? I don’t feel too strongly about it either way, though, and if it gets added people will definitely use it.
@cartant I’m definitely interested in this idea. If you’d like to create an issue with a proposal, I’d love to discuss it.
@jsayol Upon much thought, I’d like to stick to
authState
as it wraps theauthStateChanged
method. Usingstate
can be vague and does not immediately tie the two together. Interested in your thoughts though.Also I have given serious thought to scoped packaged, I even own the angularfire npm user account. I’ve been warned by many people smarter than I to avoid scoping packages unless it’s completely necessary. I’m still going to do more research, but I do think the time would be now if we were to make that change.
@IgorMinar Thanks for the feedback! I neglected to focus on upgrading TypeScript, but I definitely agree it should be a priority with this release.
Yes there will be a clear migration path. For Database users there will be only small changes. For authentication I will provide the analogous methods in the Firebase SDK.
As for versioning, we can’t change the name to
angularfire
because the AngularFire for AngularJS follows semver which will make the version numbers collide. But I am giving serious though to scoping the packages so we can use@angularfire/core
,@angularfire/database
, and etc…@harshavarun25 read the migration & docs, as @almothafar said.
But on top of that, don’t spam the repo in three–separate–places.
@davideast I am having a similar problem can you please help me fix. I am like struggling because of this.
[23:00:27] typescript: C:/Users/Harsha Varun/MyIonicProject/src/pages/third/third.ts, line: 4 Module ‘“C:/Users/Harsha Varun/MyIonicProject/node_modules/angularfire2/index”’ has no exported member ‘AuthProviders’.
L3: import {FourthPage} from ‘…/fourth/fourth’; L4: import { AuthProviders, AuthMethods, AngularFire } from ‘angularfire2’; [23:00:27] typescript: C:/Users/Harsha Varun/MyIonicProject/src/pages/third/third.ts, line: 4 Module ‘“C:/Users/Harsha Varun/MyIonicProject/node_modules/angularfire2/index”’ has no exported member ‘AuthMethods’.
L3: import {FourthPage} from ‘…/fourth/fourth’; L4: import { AuthProviders, AuthMethods, AngularFire } from ‘angularfire2’; [23:00:27] typescript: C:/Users/Harsha Varun/MyIonicProject/src/pages/third/third.ts, line: 4 Module ‘“C:/Users/Harsha Varun/MyIonicProject/node_modules/angularfire2/index”’ has no exported member ‘AngularFire’.
L3: import {FourthPage} from ‘…/fourth/fourth’; L4: import { AuthProviders, AuthMethods, AngularFire } from ‘angularfire2’; package.json “name”: “MyIonicProject”, “version”: “0.0.1”, “author”: “Ionic Framework”, “homepage”: “http://ionicframework.com/”, “private”: true, “scripts”: { “clean”: “ionic-app-scripts clean”, “build”: “ionic-app-scripts build”, “lint”: “ionic-app-scripts lint”, “ionic:build”: “ionic-app-scripts build”, “ionic:serve”: “ionic-app-scripts serve” }, “dependencies”: { “@angular/common”: “4.1.0”, “@angular/compiler”: “4.1.0”, “@angular/compiler-cli”: “4.1.0”, “@angular/core”: “4.1.0”, “@angular/forms”: “4.1.0”, “@angular/http”: “4.1.0”, “@angular/platform-browser”: “4.1.0”, “@angular/platform-browser-dynamic”: “4.1.0”, “”: “3.7.0”, “”: “3.7.0”, “”: “3.7.0”, “”: “2.0.1”, “angularfire2”: “^4.0.0-rc.0”, “firebase”: “^4.0.0”, “ionic-angular”: “3.2.1”, “ionicons”: “3.0.0”, “rxjs”: “5.1.1”, “sw-toolbox”: “3.6.0”, “zone.js”: “0.8.10” }, “devDependencies”: { “”: “1.3.7”, “”: “1.1.2”, “”: “1.1.2”, “angularfire2”: “^4.0.0-rc.0”, “typescript”: “2.2.1” }, “description”: “An Ionic project” }
Thanks in advance
@davideast Yeah, thanks!
If I import with the below syntax I’ll get all of firebase in my bundles, including messaging and storage (even if I don’t use it).
Loaded and so far so good! Did not have Auth in this simple little POC so unable to test that but the breakout is great, simplified our code a bit. Great work! Will report back if I run into any issues.
Can we get an update on this topic, please?
@harshavarun25 you really should read migration steps, also, you reached this issue, you can find the solution with comments as well.
Just updated to this, was easy as cake, and works like a charm!, thanks for your great job!
Hi, I’ve upgraded to firebase2/database. I get the following problem. How can I fix? Error: No provider for AngularFireDatabase! Gunnar
@martzcodes yup, import firebase as well. It won’t affect your bundle sizes since it’s already included by angularfire2.
Migrated today, working great with Ionic 3. Looking forward to the new release!
Migrated yesterday, works great. Like the new API. The migration was pretty straightforward, just a lot of find & replace.
Looking forward to the messaging module. Notifications in my app right now are a bit of a mess.
Just going to throw in my hat of support, this all sounds great. I would like to also see what the effort is to try and stay as current as possible on @angular. angularfire2 is still on 2.0.0 which is causing some issues with the latest cli as mentioned elsehwere and strikes me as though it could be an ongoing problem as @angular cruises through semvar.
Evolution is happening! Ionic 2 [final] has only been out for 2 months, Angular 4.0 dropped a few weeks ago, and today the first Ionic 3.0 beta was released. There is a clear need for AngularFire to evolve too.
I fully support your proposed changes. I love using AngularFire’s bindings for a few specific ‘live-data’ needs, but most of the data my apps are loading are ‘one-time’ loads. So most of the time, I’m using firebase’s snapshots to pull data.
Please move forward! Thank you!