description |
---|
A tutorial for using Ionic Framework and Firebase. |
You can either download the sample project, or follow the instructions below.
<%= include('../_includes/_package', { org: 'auth0-samples', repo: 'auth0-ionic-firebase', path: '' }) %>
Go to the Application Settings section in the Auth0 dashboard and make sure that Allowed Callback URLs contains the following values:
https://${account.namespace}/mobile, file://*, http://localhost:8100
You need to add your Firebase account information to Auth0. Once the user logs in to the App, Auth0 will use this information to issue a Firebase authentication token.
Go to Application Settings and click on Addons. In there, turn on the Firebase Addon.
Under Settings, use the Use SDK v3+ tokens slider to select the SDK version you are using.
SDK Version 2: If you are using an older version, you will only need to enter your Firebase Secret which you can get from your Firebase dashboard under Project Settings then Service Accounts then Database Secrets.
SDK Version 3+: For SDKv3 and later, you will need the Private Key and Client Email. The Private Key Id and Token Expiration fields are optional.
In your Firebase dashboard, go to Project Settings and select the Service Accounts tab. Then under Firebase Admin SDK, scroll down and click on GENERATE NEW PRIVATE KEY.
This will generate a JSON file which will contain the private_key_id
, private_key
and client_email
fields to be entered into the Addon Settings on the Auth0 dashboard. Click SAVE when you are finished.
Add the following dependencies to the bower.json
and run bower install
:
"dependencies" : {
"auth0-angular": "4.*",
"a0-angular-storage": ">= 0.0.6",
"angular-jwt": ">= 0.0.4",
"angularfire": "~0.9.2"
},
<!-- Auth0 Lock -->
<script src="lib/auth0-lock/build/auth0-lock.js"></script>
<!-- auth0-angular -->
<script src="lib/auth0-angular/build/auth0-angular.js"></script>
<!-- angular storage -->
<script src="lib/a0-angular-storage/dist/angular-storage.js"></script>
<!-- angular-jwt -->
<script src="lib/angular-jwt/dist/angular-jwt.js"></script>
<!-- Firebase dependencies -->
<script src="lib/firebase/firebase.js"></script>
<script src="lib/angularfire/dist/angularfire.js"></script>
You must install the InAppBrowser
plugin from Cordova to be able to show the Login popup. Run the following command:
ionic plugin add org.apache.cordova.inappbrowser
Add the following configuration to the config.xml
file:
<feature name="InAppBrowser">
<param name="ios-package" value="CDVInAppBrowser" />
<param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser" />
</feature>
Add the auth0
, angular-storage
, angular-jwt
and firebase
module dependencies to your angular app definition and configure auth0
by calling the init
method of the authProvider
// app.js
angular.module('starter', ['ionic',
'starter.controllers',
'starter.services',
'auth0',
'angular-storage',
'angular-jwt',
'firebase'])
.config(function($stateProvider, $urlRouterProvider, authProvider, $httpProvider,
jwtInterceptorProvider) {
$stateProvider
// This is the state where you'll show the login
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl',
})
// Your app states
.state('dashboard', {
url: '/dashboard',
templateUrl: 'templates/dashboard.html',
data: {
// This tells Auth0 that this state requires the user to be logged in.
// If a user isn't logged in and tries to access this state
// they will be redirected to the login page
requiresLogin: true
}
})
...
authProvider.init({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
loginState: 'login'
});
...
})
.run(function(auth) {
// This hooks all auth events to check everything as soon as the app starts
auth.hookEvents();
});
Now you're ready to implement the Login. You can inject the auth
service in any controller and just call signin
method to show the Login / SignUp popup.
In this case, add the call in the login
method of the LoginCtrl
controller.
After a successful login, you will:
- Save the user profile.
- Save the token and refresh token
- Call Auth0 to issue a Firebase token and save it as well.
All these artifacts are persisted into
localStorage
in the browser. The Firebase token is obtained through Auth0's Delegation endpoint.
// LoginCtrl.js
function LoginCtrl(store, $scope, $location, auth) {
$scope.login = function() {
auth.signin({
authParams: {
scope: 'openid offline_access',
device: 'Mobile device'
}
}, function(profile, token, accessToken, state, refreshToken) {
store.set('profile', profile);
store.set('token', idToken);
store.set('refreshToken', refreshToken);
auth.getToken({
api: 'firebase'
}).then(function(delegation) {
store.set('firebaseToken', delegation.id_token);
$state.go('dashboard');
}, function(error) {
// Error getting the firebase token
})
}, function() {
// Error callback
});
}
}
<!-- login.html -->
<!-- ... -->
<input type="submit" ng-click="login()" />
<!-- ... -->
Note: there are multiple ways of implementing login. The example above uses the Auth0 Lock a component that implements a ready to use login UI. You can build your own UI changing the
<script src="//cdn.auth0.com/js/auth0-lock-6.js">
for<script src="${auth0js_url}">
. This is just a non-visual authentication library. For more details check out the GitHub repo.
Just call the signout
method in Auth0 to log the user out. You should also remove the information saved into localStorage
:
$scope.logout = function() {
auth.signout();
store.remove('token');
store.remove('profile');
store.remove('refreshToken');
store.remove('firebaseToken');
$state.go('login');
}
<input type="submit" ng-click="logout()" value="Log out" />
Now that you have the Firebase token, you simply pass it to the AngularFire module using the authWithCustomToken
function:
var friendsRef = new Firebase("https://<your-account>.firebaseio.com/<your collection>");
// Here we're using the Firebase Token we stored after login
friendsRef.authWithCustomToken(store.get('firebaseToken'), function(error, auth) {
if (error) {
// There was an error logging in, redirect the user to login page
$state.go('login');
}
});
var friendsSync = $firebase(friendsRef);
var friends = friendsSync.$asArray();
friends.$add({name: 'Hey John'});
Check the AngularFire documentation for more information on all of its features.
After the user has logged in, you can get the profile
property from the auth
service. You can access all logged-in user properties:
<span>User's name is {{auth.profile.nickname}}</span>
// UserInfoCtrl.js
function UserInfoCtrl($scope, auth) {
$scope.auth = auth;
}
Click here to find out all of the available properties from a user's profile. Note that some of these depend on the social provider being used.
The user profile and the tokens are saved in localStorage
. If the page os refreshed, you just need to fetch them from the store and let auth0-angular
know that the user is already authenticated:
angular.module('myApp', ['auth0', 'angular-storage', 'angular-jwt'])
.run(function($rootScope, auth, store, jwtHelper, $location) {
// This events gets triggered on refresh or URL change
$rootScope.$on('$locationChangeStart', function() {
if (!auth.isAuthenticated) {
var token = store.get('token');
if (token) {
if (!jwtHelper.isTokenExpired(token)) {
auth.authenticate(store.get('profile'), token);
} else {
// Use the refresh token we had
auth.refreshIdToken(refreshToken).then(function(idToken) {
store.set('token', idToken);
auth.authenticate(store.get('profile'), token);
});
}
}
}
});
});
Now it's time to sit back, relax and open a beer. You've implemented Login and Signup with Auth0, Ionic and Firebase.
This means that the InAppBrowser
plugin wasn't installed successfully by Cordova. Try any of the following steps to fix this:
- Reinstall the
InAppBrowser
plugin:
ionic plugin remove org.apache.cordova.inappbrowser
ionic plugin add org.apache.cordova.inappbrowser
- Remove the platform and add it again:
ionic platform remove ios
ionic platform add ios
- Copy the contents from the plugin to the platform plugins
cp plugins/org.apache.cordova.inappbrowser/src/ios/* platforms/ios/[yourAppName]/Plugins/org.apache.cordova.inappbrowser/
This means that the InAppBrowser
plugin wasn't installed successfully by Cordova. See the previous section to learn how to solve this.