-
Notifications
You must be signed in to change notification settings - Fork 632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AngularFire 1.2 - firebaseRefProvider and $firebaseAuthService #703
Changes from 11 commits
0d69e18
3391ca6
e9b3875
46c0936
10a0f22
143715d
7c3fae6
cbc00b2
c0ce895
2a6a943
8132ec9
052f4a6
a7554c6
ca77e25
eaa688e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
(function() { | ||
"use strict"; | ||
|
||
function FirebaseAuthService($firebaseAuth, firebaseRef) { | ||
return $firebaseAuth(firebaseRef); | ||
} | ||
FirebaseAuthService.$inject = ['$firebaseAuth', 'firebaseRef']; | ||
|
||
angular.module('firebase') | ||
.factory('$firebaseAuthService', FirebaseAuthService); | ||
|
||
})(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
(function() { | ||
"use strict"; | ||
|
||
function FirebaseRef() { | ||
this.urls = null; | ||
this.registerUrl = function registerUrl(urlOrConfig) { | ||
|
||
if (typeof urlOrConfig === 'string') { | ||
this.urls = {}; | ||
this.urls.default = urlOrConfig; | ||
} | ||
|
||
if (angular.isObject(urlOrConfig)) { | ||
this.urls = urlOrConfig; | ||
} | ||
|
||
}; | ||
|
||
this.$$checkUrls = function $$checkUrls(urlConfig) { | ||
if (!urlConfig) { | ||
return new Error('No Firebase URL registered. Use firebaseRefProvider.registerUrl() in the config phase. This is required if you are using $firebaseAuthService.'); | ||
} | ||
}; | ||
|
||
this.$$createRefsFromUrlConfig = function $$createMultipleRefs(urlConfig) { | ||
var error = this.$$checkUrls(urlConfig); | ||
if (error) { throw error; } | ||
var defaultUrl = urlConfig.default; | ||
var defaultRef = new Firebase(defaultUrl); | ||
delete urlConfig.default; | ||
angular.forEach(urlConfig, function(value, key) { | ||
if (!defaultRef.hasOwnProperty(key)) { | ||
defaultRef[key] = new Firebase(value); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only methods directly declared on the Firebase ref will cause hasOwnProperty() to return true. It does not traverse the prototype chain:
Thus, inherited or a non-enumerable property will return false and get overwritten. Overall, I'm not particularly happy with the idea of modifying the Firebase reference; other gotchas like this one may be waiting to trip us up. Are there better alternatives? I know it's slightly less fun, but maybe just always placing the default at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After reviewing it, I agree. I think modifying the Firebase ref can open up a can of worms. |
||
} else { | ||
throw new Error(key + ' is a reserved property name on firebaseRef.'); | ||
} | ||
}); | ||
return defaultRef; | ||
}; | ||
|
||
this.$get = function FirebaseRef_$get() { | ||
return this.$$createRefsFromUrlConfig(this.urls); | ||
}; | ||
} | ||
|
||
angular.module('firebase') | ||
.provider('firebaseRef', FirebaseRef); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We've deviated here. All our other factories are prefixed with $, but firebaseRef is not. Unless you have a strong justification, let's be consistent because that's what we do. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was under the impression that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We used it for everything. I guess let's be consistent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd still like to see this changed. Do you feel strongly about not prefixing with $? All our other services follow this convention. |
||
|
||
})(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
'use strict'; | ||
describe('$firebaseAuthService', function () { | ||
var firebaseRefProvider; | ||
var MOCK_URL = 'https://stub.firebaseio-demo.com/' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want |
||
|
||
beforeEach(module('firebase', function(_firebaseRefProvider_) { | ||
firebaseRefProvider = _firebaseRefProvider_; | ||
firebaseRefProvider.registerUrl(MOCK_URL); | ||
})); | ||
|
||
describe('<constructor>', function() { | ||
|
||
var $firebaseAuthService; | ||
beforeEach(function() { | ||
module('firebase'); | ||
inject(function (_$firebaseAuthService_) { | ||
$firebaseAuthService = _$firebaseAuthService_; | ||
}); | ||
}); | ||
|
||
it('should exist based on using firebaseRefProvider.registerUrl()', inject(function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does |
||
expect($firebaseAuthService).not.toBe(null); | ||
})); | ||
|
||
}); | ||
|
||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
'use strict'; | ||
describe('firebaseRef', function () { | ||
|
||
var firebaseRefProvider; | ||
var MOCK_URL = 'https://stub.firebaseio-demo.com/' | ||
|
||
beforeEach(module('firebase', function(_firebaseRefProvider_) { | ||
firebaseRefProvider = _firebaseRefProvider_; | ||
})); | ||
|
||
describe('registerUrl', function() { | ||
|
||
it('creates a single reference with a url', inject(function() { | ||
firebaseRefProvider.registerUrl(MOCK_URL); | ||
expect(firebaseRefProvider.$get()).toBeAFirebaseRef(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
})); | ||
|
||
it('creates a default reference with a config object', inject(function() { | ||
firebaseRefProvider.registerUrl({ | ||
default: MOCK_URL | ||
}); | ||
var firebaseRef = firebaseRefProvider.$get(); | ||
expect(firebaseRef).toBeAFirebaseRef(); | ||
})); | ||
|
||
it('creates multiple references with a config object', inject(function() { | ||
firebaseRefProvider.registerUrl({ | ||
default: MOCK_URL, | ||
messages: MOCK_URL + 'messages' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah the endless debate about whether we should suffix the root URL or concat all child paths with a separator. Reminds me of my old PHP days and little beauties like this: There's nothing to see here. Move along. |
||
}); | ||
var firebaseRef = firebaseRefProvider.$get(); | ||
expect(firebaseRef).toBeAFirebaseRef(); | ||
expect(firebaseRef.messages).toBeAFirebaseRef(); | ||
})); | ||
|
||
it('should throw an error when no url is provided', inject(function () { | ||
function errorWrapper() { | ||
firebaseRefProvider.registerUrl(); | ||
firebaseRefProvider.$get(); | ||
} | ||
expect(errorWrapper).toThrow(); | ||
})); | ||
|
||
it('should throw an error when a reserved property is used', inject(function() { | ||
function errorWrapper() { | ||
firebaseRefProvider.registerUrl({ | ||
path: 'hello' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to see a |
||
}); | ||
firebaseRefProvider.$get(); | ||
} | ||
expect(errorWrapper).toThrow(); | ||
})); | ||
|
||
}); | ||
|
||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't use
$inject
anywhere else. Note that I don't dislike this approach and I even find it more readable, but it's inconsistent, and if we're going to change the strategy, we should do that in a sep changelist.The current format is:
angular.module('firebase').factory('$firebaseAuthService', ["$firebaseAuth", "firebaseRef", FirebaseAuthService])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the proposed structure in the Angular Styleguide, which is supported by the core team.
I would like for us to move that way eventually. I think starting here is fine because of how small and isolated it is from the rest of the codebase.