I want to add a push token to an user in my application. I have the push token, I have the user, but I can't add the token to the user. How I can add the push token to this user?
Here is the code:
var io = Ionic.io();
username = localStorage.getItem('username');
var signupSuccess = function(user) {
// The user was authenticated; you can get the authenticated user
console.log(user);
};
var signupFailure = function(errors) {
for (var err in errors) {
// Check the error and provide an appropriate message
// for your application.
user = Ionic.User.current();
}
};
var details = {
'email': 'email#gmail.com',
'password': 'pass2',
'username': 'username'
}
Ionic.Auth.signup(details).then(signupSuccess, signupFailure);
var push = new Ionic.Push();
var user = Ionic.User.current();
var callback = function(pushToken) {
alert('TOKEN: ' + pushToken.token);
user.addPushToken(pushToken);
user.save(); // You NEED to call a save after you add the token
}
push.register(callback);
It's no longer user.addPushToken(pushToken);
Instead you need:
push.register(function(token) {
push.saveToken(token);
});
This will automatically add the token to the currently logged in Ionic user.
See this example from Ionic documentation
N.B. as you're adding this at the point that the user is signing in, you also need to add the above code to register for push inside your $ionicPlatform.ready function:
$ionicPlatform.ready(function() {
var push = new Ionic.Push();
push.register(function(token) {
push.saveToken(token);
});
});
Or more likely, create one function to register for push which is called both from within $ionicPlatform.ready and also from within your signup / signin functions.
Otherwise, if Push has not been registered inside $ionicPlatform.ready, it won't add the token to your user when you call push.saveToken after signup / signin.
I can suggest one thing. You can ask the backend or server to team add a user token in the database or else.
You can manually add the following thing if it is an JSON object:
user["token"]=value
Related
I have a flutter app that needs access to multiple user's calendars.
I can get access for one user working, but the access grant is only temporary and the user gets re-prompted every time. I want to develop something like the firebase google authentication and many other Oauth examples: You get prompted once to grant access and then the access is granted offline until you revoke the access grant.
How can I request access with the remembered credentials? Here is my code:
final ClientId _userAccountCredentials = new ClientId(
"XXXXX.apps.googleusercontent.com",
"");
void prompt(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
void getCalendarEventsOnline() {
clientViaUserConsent(_userAccountCredentials, scopes, prompt).then((AuthClient client) {
var calendar = calendarapi.CalendarApi(client);
var calEvents = calendar.events.list("primary");
calEvents.then((calendarapi.Events events) {
/// some logic within
});
client.close();
});
}
I tried using a service account, but impersonating a user works only for a Gsuite account
Asking each user to add the service account to their calendar is error-prone, clumsy and unacceptable for non-technical users (think your grandparents), given that many popular services can do this directly
I discovered that the client contains all the information I need for future calls:
debugPrint(' access token: ' + client.credentials.accessToken.data +' refresh token ' + client.credentials.refreshToken);
// store the tokens in the apps key store
When my user makes a new call a second or a year from now, I retrieve the tokens from storage, create new credentials and make my calls:
AccessCredentials _newCredentials = AccessCredentials(fromStorage.credentials.accessToken,
fromStrorage.credentials.refreshToken, _scopes );
var _newClient = new http.Client();
AccessCredentials _accessCredentials = await refreshCredentials( _clientID, newCredentials , _newClient);
_newClient = authenticatedClient(_newClient, _accessCredentials);
// the code below was just for me to test this out with my API scopes. replace with your code
var calendar = cal.CalendarApi(_newClient);
String calendarId = "---some string---";
cal.FreeBusyRequest _request = cal.FreeBusyRequest.fromJson(
{
'items': [
{'id': calendarId, 'busy': 'Active'}
],
'timeMin': (new DateTime(2020, 11, 17)).toIso8601String()+'Z',
'timeMax': (new DateTime(2020, 11, 19)).toIso8601String()+'Z'
});
debugPrint('request: ' + _request.toJson().toString());
cal.FreeBusyResponse response = await calendar.freebusy.query(_request);
debugPrint(response.toJson().toString());
});
I can't seem to understand the relation between Accounts.createUser() and Accounts.onCreateUser(). I have an external api that validates the users' login credentials. Once the api sends me a positive response, I need to add the user in MongoDB and start its session so it can be considered as a logged in user. Accounts.createUser() is creating a user on server side, but I need Accounts.onCreateUser() because I need to add custom fields like user's token that is being generated from the external api.
This is the code I have right now (which doesn't add a user at all):
server-side code:
var request = {
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
'params': user
};
try {
var response = HTTP.call('POST', url, request); //send call to the external api
var token = response.data.token;
//decode the token and add the user in the database
var userInfo = Base64.decode(token.split('.')[1]);
var options = {
email: user._username,
profile: {
name: user._username
},
token: token
};
var user = Accounts.onCreateUser(function(options, user) {
if (options.token)
user.token = options.token;
if (options.profile)
user.profile = options.profile;
return user;
});
console.log(user); //this returns undefined
return JSON.stringify({
'code': 200,
'token': userInfo
});
} catch (error) {
console.log(error);
//console.log(error.response);
var body = error.response.content;
return body;
}
Okay. So I finally found what I had been looking for. The relation between Accounts.createUser and Accounts.onCreateUser is that Accounts.onCreateUser is a hook and adds extended functionality to the original Accounts.createUser function. What is the extended functionality? It lets you create additional fields prior to actually inserting your user in the database. You have to write this hook in your main.js (server side) in the startup code snippet:
Meteor.startup(() => {
Accounts.onCreateUser(function(options, user) {
if (options.token)
user.token = options.token;
if (options.profile)
user.profile = options.profile;
return user;
});
})
And wherever you want to add the user, simply call Accounts.createUser() and this hook will be called automatically prior to the createUser call
I am working on google auth with firebase signinwithcredential. I first used cordovaoath to get the id token and sign it in with firebase. I specifically indicated in my code that I would like to get the displayName, but it always come back null. I was wondering anyone have faced the same problem?
this.loginWithGoogle = function loginWithGoogle() {
$cordovaOauth.google("mygoogleclient id here", ["https://www.googleapis.com/auth/calendar","https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/plus.me", "https://www.googleapis.com/auth/plus.login", "https://www.googleapis.com/auth/drive"]).then(function (result) {
// "email", "profile",
console.log("first come here to oath");
console.log("Response Object -> " + JSON.stringify(result));
var unsubscribe = firebase.auth().onAuthStateChanged(function (firebaseUser) {
unsubscribe();
// Check if we are already signed-in Firebase with the correct user.
// Build Firebase credential with the Google ID token.
var credential='';
credential = firebase.auth.GoogleAuthProvider.credential(
result.id_token);
// Sign in with credential from the Google user.
firebase.auth().signInWithCredential(credential).catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
});
});
}, function (error) {
console.log("Error -> " + error);
});
};
sreenshot of my returned result
You should request an access token, and not an ID token, if you are requesting additional scopes.
To fix your code, change this line:
var credential = firebase.auth.GoogleAuthProvider.credential(
null, result.access_token); // <- access_token
I have implemented single sign on using the WL api, but I only recently realized that I need to call mobileService.login on top of that to use the nice authentication features of Azure Mobile Services.
I followed this tutorial
http://www.windowsazure.com/en-us/develop/mobile/tutorials/single-sign-on-windows-8-js/#add-authentication
and added this piece of code:
var login = function () {
return new WinJS.Promise(function (complete) {
WL.init();
WL.login({ scope: ["wl.signin", "wl.basic", "wl.birthday", "wl.emails"] }).then(function (result) {
session = result.session;
WinJS.Promise.join([
WL.api({ path: "me", method: "GET" }),
mobileService.login("microsoftaccount", session.authentication_token)
]).done(function (results) {
var profile = results[0];
var mobileServicesUser = results[1];
var title = "Welcome " + profile.first_name + "!";
var message = "You are now logged in as: " + mobileServicesUser.userId;
var dialog = new Windows.UI.Popups.MessageDialog(message, title);
dialog.showAsync().done(complete);
});
}, function (error) {
session = null;
var dialog = new Windows.UI.Popups.MessageDialog("You must log in.", "Login Required");
dialog.showAsync().done(complete);
});
});
}
however on this line
mobileService.login("microsoftaccount", session.authentication_token)
my session.authentication_token is undefined. (I have an access_token)
If I don't pass the token, I am prompted to sign in every time I launch the app, which defeats the purpose of the integrated sign on.
Any ideas?
To get the authentication token, you need to pass the redirect URI to the call to WL.init:
WL.init({
redirect_uri: "<< INSERT REDIRECT DOMAIN HERE >>"
});
Where the redirect domain must be the same as the one in your Live Connect application.
Currently I have a store that I am loading in my app.js at runtime:
stores: ['Neighbors']
Its autoLoad property is set to true.
I've now added a login system that is loaded if some info isn't found in localStorage:
//show login if user credentials are unknown
var username = window.localStorage.getItem("email");
var user_id = window.localStorage.getItem("user_id");
if(username == '' || username == undefined || user_id == '' || user_id == undefined) {
Ext.Viewport.add(Ext.create('aa.view.Login'));
} else {
Ext.Viewport.add(Ext.create('aa.view.Main'));
}
The login view fires an ajax request to log the user in, and the user's id and some other info is returned on success:
onLoginButtonTap: function() {
var values = this.getLoginForm().getValues();
var that = this;
// do the ajax login
Ext.Ajax.request({
url: 'http://localhost:8000/session',
method: 'POST',
params: values,
timeout: 10000, // time out for your request
success: function(result) {
// let's get the email and id into local storage
var json = Ext.decode(result.responseText);
console.log(json);
window.localStorage.setItem('user_id', json.user_id);
window.localStorage.setItem('email', json.email);
// var neighborsStore = Ext.getStore('Neighbors');
// neighborsStore.load();
// load up the tab holder and destroy the login view
Ext.getCmp('loginForm').destroy();
Ext.Viewport.add(Ext.create('aa.view.Main'));
},
failure: function(){
Ext.Msg.alert("Login Failed");
}
});
}
I use the user_id in my store to get a list of other users nearby. The only problem is, my user_id isn't known unless my user has logged in.
I either need to refresh the store, or I need to defer its loading until after a successful login. I'd rather do the second option and only attempt to load the store after login.
I can't seem to find any info on how to do this. I've tried
Ext.getStore('storename').load()
but it isn't refreshing the store. I've tried setting autoLoad to false but then the store never loads. How do I defer loading?
You should be able to use that.getNeighborsStore().load() in your success function. This will load the store once the user has successfully logged in.