I have an inherited Ionic framework app that is using Ionic.io
The app authorises against our API, and is given an API token to use in future requests.
I'm trying to work on push notifications - I've set up ionic push, and can trigger push notifications out to all users with no problems.
I'd like the ability to target specific users / devices to send notifications, and I understand that to do this, I have to register the device to generate a token.
Within my $ionicPlatform.ready function, I have:
$ionicPush.register().then(function(t) {
return $ionicPush.saveToken(t);
}).then(function(t) {
console.log('Token saved:', t.token);
});
This however does not seem to be returning a token, and calling
console.log($ionicPush);
Shows that the token is not set.
Any ideas here? What am I missing?
So after digging though some documentation, I found that the issue was linked with the ionic user.
In the main run function, I fire off a
if ($ionicAuth.isAuthenticated()) {
If this fails, I try a login of a user, and a register of the user if appropriate. (user is already logged in using a custom auth token against our api)
Before I attempt to register the token, I then have to reload the user in order to have the app save off and push back up to ionic.io.
$ionicUser.load().then(function() {
$ionicPush.register().then(function(t) {
console.log('Token sent:', t.token);
return $ionicPush.saveToken(t);
}).then(function(t) {
console.log('Token saved:', t.token);
});
});
Related
Is there a way to get the token outside the register method later in the code?
I mean, is the token assigned to an attribute of the Push object somewhere?
push.on('registration', (data) => {
// console.log("device token ->", data.registrationId);
//TODO - send device token to server
});
The above code works to see the token, yet it is outside of my controllers or providers. I have to access it later in my code. I want to send the token to server, but for this I first have to get the user name. Since push registration happens somewhen when device ready, I yet do not have access to the user name. Another problem is for new users where token can not be assigned to a specific user yet and send device token to server can not be executed.
You can use localStorage.
setItem
localStorage.setItem('device_token', data.registrationId);
and use it like this
getItem
this.device_token = localStorage.getItem('device_token');
I want to add Facebook login to my Alloy/ Titanium ios app.
So far I have the following code:
var fb = require('facebook');
fb.initialize();
fb.setLoginBehavior(fb.LOGIN_BEHAVIOR_NATIVE);
fb.permissions = ['email', 'public_profile'];
function doFacebookLogin() {
// occurs when a button is clicked
if (fb.loggedIn) {
facebookLogin(fb);
} else {
fb.authorize();
}
}
fb.addEventListener('login', function(event) {
if (event.success) {
facebookLogin(fb);
}
});
function facebookLogin(fb) {
Ti.API.info(fb.accessToken);
// send the fb.accessToken server-side and register & login the user
}
For the most part the code works fine!
The issue is when the user de-authorises the app, fb.login still return true and so is using the same access token.
How can I check if the user has de-authorised my app. I know it's easily possible using the JavaScript SDK using FB.getLoginStatus: https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus , but I can't find an equivalent in Alloy/Titanium: https://docs.appcelerator.com/platform/latest/#!/api/Modules.Facebook
You need to call fb.logout() to set fb.loggedIn to false.
fb.logout clears the access token and resets the login state to false.
Note: I am not sure whether clearing the access token in Titanium module will also clear the token on FB server. So even after calling fb.logout(), you might receive the same access token if and only if it has not expired on fb server.
Read more about Facebook Access Token here
I am building an Ionic/Phonegap app with a Firebase backend.
Login
Followed the example from the official AngularFire documentation for login:
// Check sign-in data
$scope.signIn = function(user, password) {
// Log in
$scope.auth.$authWithPassword({
email : user,
password : password
})
// If successful
.then(function(authData) {
console.log('worked');
// Further code
}
// If failure, alert
.catch(function(error) {
console.log(error);
}
}
Login works fine.
Logout
For logout I also copied the example from the documentation:
$scope.logout = function() {
// Manually disconnect from database
Firebase.goOffline();
// Log user out
$scope.auth.$unauth();
// Go to landing page
$state.go('signin');
};
Seems to work as well (when I'm asking for the current authentication state of the user after logging out $getAuth() returns null).
Login after Logout
But if I'm now trying to log in again, nothing happens - no error, no success message. So neither of the console.logs triggers.
I need to close and open the app again or refresh the browser window in order to be able to log in again. Can anyone tell me what I'm doing wrong here?
Versions
Using the latest versions:
Ionic 1.2.4
Firebase 2.4.0
AngularFire 1.1.3
Remove the Firebase.goOffline() from your logout. If you want to manually manage Firebase connection then you should consider adding Firebase.goOnline() during login.
Auth.$unauth() will take care of logging out the user, you do not have to disconnect Firebase manually.
I've got a Meteor application with a multi-phase sign-up process. The accounts are based on the accounts-password package. In the step prior to account creation, the user needs to provide some profile information.
I'd like the user to be able to launch a Facebook OAuth flow which pre-populates the profile fields with information pulled from Facebook.
This all needs to happen pre-account-creation. I want to implement this with the facebook package that backs accounts-facebook.
At the moment I've got the OAuth flow happening by calling Facebook.requestCredential, but I'm not sure how to get an OAuth access token from the credential token that comes back. I suspect I need to pass this to the server and make an API call to get back an access token.
Any pointers as to how this should work would be much appreciated.
Facebook.requestCredential(function (credentialTokenOrError) {
if (credentialTokenOrError && credentialTokenOrError instanceof Error) {
// Error...
console.log(credentialTokenOrError);
} else {
// Credential Token string
console.log(credentialTokenOrError);
// Now perhaps a Meteor.call to a server method that
// 1. Retrieves an access token
// 2. Hits the graph API to get profile information and returns it to the client
}
});
Thanks,
Chris
I was having the same trouble of converting a credentialToken to an accessToken, only with Github. I've written up a gist that has code that should work very similarly. Essentially, there are two steps:
Within your Facebook.requestCredential callback function, call OAuth._retrieveCredentialSecret(tokenOrError), the result of which is the credentialSecret. Then use Meteor.call, passing in tokenOrError and credentialSecret, to call the Meteor.method you'll set up in the next step.
code (on client):
Github.requestCredential({
loginStyle: 'popup',
requestPermissions: ['gist']
}, function(tokenOrError) {
if (tokenOrError && tokenOrError instanceof Error) {
// Throw a Meteor error
console.log('error getting the token');
return;
}
var credentialSecret = OAuth._retrieveCredentialSecret(tokenOrError);
Meteor.call('getGithubAccessToken', tokenOrError, credentialSecret, function(err, accessToken) {});
});
On the server, set up a Meteor.method that takes your credentialToken and credentialSecret and calls Facebook.retrieveCredential. This function returns a credentials object from the _pendingCredentials Mongo Collection before deleting it from the collection. The access token is credentials.serviceData.accessToken. The credentials object could potentially be persisted in the user object in the Meteor.users collection (as it is in the accounts packages) or sent back to the user.
code (on server):
Meteor.methods({
getGithubAccessToken: function(credentialToken, credentialSecret) {
var credentials = Github.retrieveCredential(credentialToken, credentialSecret);
console.log('accessToken:', credentials.serviceData.accessToken);
return credentials.serviceData.accessToken;
}
});
I'm unfamiliar with the specifics of Facebook's Graph API so after these steps, you're on your own. Good luck!
I'm pretty new to Angular, and right now I'm just trying to get all my routes set up and working as I'd like.
Setup:
When a user navigates to certain pages (/settings for this example) the app should check if there is a user already logged in. If there is continue as usual. Otherwise the user should go to the login page (/login).
What I'd like:
After the user has successfully logged in they should go to the page they were originally trying to get to (/settings)
My question:
Is there an "Angular way" to remember where the user was trying to go to?
Relevant code:
app.js
.when('/settings', {
templateUrl: '/views/auth/settings.html',
controller: 'SettingsCtrl',
resolve: {
currentUser: function($q, $location, Auth) {
var deferred = $q.defer();
var noUser = function() {
//remember where the user was trying to go
$location.path("/login")
};
Auth.checkLogin(function() {
if (Auth.currentUser()) {
deferred.resolve(Auth.currentUser());
} else {
deferred.reject(noUser());
}
});
return deferred.promise;
}
}
})
login.js
$scope.submit = function() {
if(!$scope.logInForm.$invalid) {
Auth.login($scope.login, $scope.password, $scope.remember_me)
//go to the page the user was trying to get to
}
};
Much thanks to John Lindquist for the video which got me this far.
First off, you do not want to redirect the user to a login page.
An ideal flow in a single page web app is as follows:
A user visits a web site. The web site replies with the static assets for the
angular app at the specific route (e.g. /profile/edit).
The controller (for the given route) makes a call to an API using $http, $route, or other mechanism (e.g. to pre-fill the Edit Profile form with details from the logged in user's account via a GET to /api/v1/users/profile)
If/while the client receives a 401 from the API, show a modal to
login, and replay the API call.
The API call succeeds (in this case, the user can view a pre-filled Edit Profile form for their account.)
How can you do #3? The answer is $http Response Interceptors.
For purposes of global error handling, authentication or any kind of
synchronous or asynchronous preprocessing of received responses, it is
desirable to be able to intercept responses for http requests before
they are handed over to the application code that initiated these
requests. The response interceptors leverage the promise apis to
fulfil this need for both synchronous and asynchronous preprocessing.
http://docs.angularjs.org/api/ng.$http
Now that we know what the ideal user experience should be, how do we do it?
There is an example here: http://witoldsz.github.com/angular-http-auth/
The example is based on this article:
http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application
Good luck and happy Angularing!