I am trying to send a push notification after a user's status update has changed (status update is managed in the submission class in parse core data) but I'm using cloud code to match users phone numbers in the User and submission classes so that the push notification only targets the one specific user.
Parse.Cloud.afterSave("submission", function(request) {
var statusText = request.object.get('status');
var phoneNumber = request.object.get('Phone');
Parse.Cloud.afterSave("User", function(request) {
var userPhone = request.object.get('Phone');
var pushQuery = new Parse.Query(Parse.submission);
pushQuery.matchesQuery(userPhone, phoneNumber);
Parse.Push.send({
where: pushQuery, // Set our Installation query
data: {
alert: "Status Change: " + statusText
}
}, {
success: function() {
},
error: function(error) {
throw "Got an error " + error.code + " : " + error.message;
}
});
});
Related
I'm trying to write a client-side JS script that will fetch images from my gDrive to display on a website using a service account. I created the service account and added and enabled the google Drive API for the project. But when I run the script, I'm getting a 403 error: Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup. I think it has to do with permissions or scopes maybe? I've looked at several other stack overflows and can't seem to figure it out.
Getting a 403 - Forbidden for Google Service Account
Google Drive service account returns 403 usageLimits
Some of them mention adding roles or scopes, but I can't figure out how to add them or which ones I need to add. Is a GSuite account mandatory? It sounds like I would need to go into the GSuite admin console to add the scopes? I would like to not have to sign up for an account, as it's not free. Any help would be appreciated. My code looks like the following:
function gDrive() {
function init(callback) {
authorizeClient(getJWT()).then(function(token) {
loadClient(token, callback);
});
}
/* Retrieve a signed JWT */
function getJWT() {
// Prepare header, payload, and key
let oHeader = {
"alg": "RS256",
"typ": "JWT"
};
let sHeader = JSON.stringify(oHeader);
let oPayload = {
"iss": "SERVICE ACCOUNT EMAIL",
"sub": "SERVICE ACCOUNT EMAIL",
"aud": "https://www.googleapis.com/oauth2/v3/token",
"iat": KJUR.jws.IntDate.getNow(),
"exp": KJUR.jws.IntDate.get("now + 1hour"),
"scope": "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/drive.photos.readonly https://www.googleapis.com/auth/drive.readonly"
};
let sPayload = JSON.stringify(oPayload);
let privKey = "-----BEGIN PRIVATE KEY-----BLAH BLAH BLAH\n-----END PRIVATE KEY-----\n";
// Sign JWT
return signedJWS = KJUR.jws.JWS.sign(null, sHeader, sPayload, privKey);
}
/* Http POST to Google Auth api */
function authorizeClient(JWS) {
// Request access token
const url = "https://www.googleapis.com/oauth2/v3/token";
let encodedData = "";
let encodedDataPairs = [];
encodedDataPairs.push(encodeURIComponent("grant_type") + '=' + encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"));
encodedDataPairs.push(encodeURIComponent("assertion") + '=' + encodeURIComponent(JWS));
encodedData = encodedDataPairs.join('&').replace(/%20/g, '+');
const params = {
headers: {"content-type":"application/x-www-form-urlencoded"},
body: encodedData,
method: "POST"
};
return fetch(url, params).then(accessTokenSucces).then(returnToken).catch(accessTokenFailed);
}
function accessTokenSucces(data) {
console.log("Retrieved access token");
return data.json();
}
function returnToken(resp) {
return resp.access_token;
}
function accessTokenFailed(error) {
console.log("Requesting access token failed: " + error);
}
function loadClient(accessToken, callback) {
gapi.load('client', function() {
console.log("loading client");
gapi.client.setToken(accessToken);
console.log("set access token");
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/drive/v3/rest").then(clientLoadSuccessful).then(callback).catch(clientLoadFailed);
})
}
function clientLoadSuccessful() {
console.log("Client loaded");
return Promise.resolve();
}
function clientLoadFailed(error) {
console.log("Loading Client failed: " + error);
return Promise.reject();
}
function fetchAllImages(fileName, chapter, callback) {
console.log("fetching images");
let initialRequest = gapi.client.drive.files.list({"q": "mimeType contains \"image\" and name contains '"
+ fileName + "_ch" + chapter + "'"});
retrievePageOfFiles(initialRequest, [], fileName, chapter);
function retrievePageOfFiles(request, result) {
request.execute(function(resp) {
result = result.concat(resp.files);
let nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = gapi.client.drive.files.list({
"pageToken": nextPageToken,
"q": "mimeType contains \"image\" and name contains '" + fileName + "_ch" + chapter + "'"
});
retrievePageOfFiles(request, result);
} else {
console.log("Images retrieved");
callback(result);
}
}).catch(function(err) {
console.log("Could not retrieve images: " + err);
});
}
}
return {
init: init,
fetchAllImages: fetchAllImages
};
}
gDrive().init(runApp);
function runApp() {
console.log("Running App");
gDrive().fetchAllImages("FILENAME", "1", imageCallback);
}
function imageCallback(data) {
console.log("Images Retrieved!");
console.log(data);
}
When your script is run, the error of Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup. occurs.
You want to remove this error.
If my understanding is correct, how about this modification? I think that the access token retrieved with your script can be used. So please modify your script as follows.
From:
gapi.client.setToken(accessToken);
To:
gapi.client.setToken({access_token: accessToken});
Reference:
gapi.client.setToken(tokenObject)
If this was not the direct solution of your issue, I apologize.
I am making a chat application which requires users to log in, I have so far managed to get the login system working by using UserApp.io, but I cant seem to find a way which would send a "Callback" back to the user who has emited the information to the server.
So for index.html, when a login form is submitted, it would gather the values of the two fields and emit the data to the backend.
$('form#login').submit(function() {
var data = {};
data.email = $("#login_email").val();
data.password = $("#login_password").val();
socket.emit('user login', data);
});
In the index.js file, it receives the details and checks using the UserApp API that the user is valid and all the details are correct. It also retrieves information like the first and last name.
socket.on('user login', function (user) {
logger.info('Receiving login info for "' + user.email + '"...');
UserApp.User.login({"login": user.email, "password": user.password}, function (error, result) {
if (error) {
logger.error('Login failed: ' + error.message);
} else {
var userToken = result.token;
var userID = result.user_id;
console.log("User has logged in.");
UserApp.User.get({
"user_id": userID
}, function (error, result) {
if (error) {
logger.error(error.message);
} else {
logger.info(result[0]['first_name'] + " " + result[0]['last_name'] + " Has logged in!")
}
});
}
});
});
So here is my issue. I cant seem to find a way of giving a callback to index.html so it can show errors like "Incorrect username".
So is there a way of giving a callback to one person, more specificly, the person who submitted the login form?
Any help would be appreciated.
Thanks.
socket.io has acknowledgement callbacks, here are the docs
http://socket.io/docs/#sending-and-getting-data-(acknowledgements)
Add a callback function as the third argument when emitting
$('form#login').submit(function() {
var data = {};
data.email = $("#login_email").val();
data.password = $("#login_password").val();
socket.emit('user login', data, function (result) {
console.log(result);
});
});
and then the callback function server side can have an additional parameter which is the callback you defined when emitting
socket.on('user login', function (user, callback) {
logger.info('Receiving login info for "' + user.email + '"...');
UserApp.User.login({"login": user.email, "password": user.password}, function (error, result) {
if (error) {
logger.error('Login failed: ' + error.message);
} else {
var userToken = result.token;
var userID = result.user_id;
console.log("User has logged in.");
UserApp.User.get({
"user_id": userID
}, function (error, result) {
if (error) {
logger.error(error.message);
} else {
logger.info(result[0]['first_name'] + " " + result[0]['last_name'] + " Has logged in!")
return callback('your results');
}
});
}
});
});
I want to add users to my Parse.Role but it's not working. I looked at a number of examples and they all seem pretty straight-forward however I'm unable to get it right. Here is my code:
Parse.Cloud.define("activateVendor", function(request, response){
var query = new Parse.Query(Parse.Role);
query.equalTo("name", "vendor");
query.first ({
success: function(role) {
role.getUsers().add(request.params);//request.params is the parse object, should I be using request.params.id?
role.save();
},
error: function(error) {
throw "Got an error " + error.code + " : " + error.message;
}
})
});
It depends on who you wish added to the role. The user who made the cloud request is available via the request object...
role.getUsers().add(request.user);
Otherwise, you can get a user via a query as #RobertRowntree suggests. (though, I'd suggest doing it with promises).
does what you want with 2 queries (Role, User) ...
var qu = new Parse.Query(Parse.User);
var qr = new Parse.Query(Parse.Role);
Parse.Cloud.useMasterKey();
qr.get(roleId, {
success: function(role) {
_role = role;
qu.get(userId, {
success: function(user) {
_role.getACL().setRoleReadAccess(_role, true);
_role.getUsers().add(user);
_role.save();
response.success(_role.toJSON());
},
error: function(object, error) {
}
});
},
error: function(object, error) {
}
});
My app is in the early development stage. I'm using the latest PhoneGap Build and Facebook Connect plugin. I managed to get the login working - you tap the Login With Facebook button, it switches to the Facebook app, Facebook passes my app an object with the basic login key/token & userID, and then my app tries to reach out for the user's full name and age.
I can't seem to get Facebook to give me any information other than the user's ID and full name. I need the user's age! For some reason, adding a projection isn't working... What's wrong with my code?
var fbLoginSuccess = function (userData) {
facebookConnectPlugin.getAccessToken(function(token) {
if(userData['status'] == 'connected'){
getBasicUserInfo_fb(userData);
}
}, function(err) {
alert("Could not get access token: " + err);
});
}
function getBasicUserInfo_fb(userData){
facebookConnectPlugin.api(userData['authResponse']['userID'] + "/?fields=id,birthday", ["user_birthday"], function (response) {
if (response && !response.error) {
alert("response: " + JSON.stringify(response));
console.log(response);
var user_name = response['name'];
var user_age = response['birthday'];
var user_picture = response['picture'];
}
},
function (error) {
console.log(error);
alert("Failed: " + JSON.stringify(error));
});
}
The Github page (https://github.com/Wizcorp/phonegap-facebook-plugin) says:
Getting a User's Birthday
Using the graph api this is a very simple task:
facebookConnectPlugin.api("<user-id>/?fields=id,email", ["user_birthday"],
function (result) {
alert("Result: " + JSON.stringify(result));
/* alerts:
{
"id": "000000123456789",
"email": "myemail#example.com"
}
*/
},
function (error) {
alert("Failed: " + error);
});
I might be losing my mind but the example on Github is saying how to get the birthday, and the scope is set up to get that, BUT then the parameters are set up to get the email address. Basically all I've done is changed "id,email" to "id,birthday"... What am I doing wrong?!
Apparently I was wrong to have "user_profile" in my initial login request... I guess it only accepts one parameter?
The bad version:
facebookConnectPlugin.login(["public_profile","user_birthday"],
fbLoginSuccess,
function (error) { alert("" + error) }
);
The good version:
facebookConnectPlugin.login(["user_birthday"],
fbLoginSuccess,
function (error) { alert("" + error) }
);
I'm trying to use Parse.com to sign users up to my application I'm developing. However I seem to get an error when firing my function.
Parse.initialize("APP ID", "JS KEY");
function signUp() {
var user = new Parse.User();
// Get user inputs from form.
var username = document.login.username.value;
var password = document.login.password.value;
user.set("username", username);
user.set("password", password);
user.signUp(null, {
success: function (user) {
// Hooray! Let them use the app now.
alert("Success");
},
error: function (user, error) {
// Show the error message somewhere and let the user try again.
alert("Error: " + error.code + " " + error.message);
}
});
};
The error:
Error: 100 XMLHttpRequest failed: {"statusText":"","status":0,"response":"","responseType":"","responseXML":null,"responseText":"","upload":{"ontimeout":null,"onprogress":null,"onloadstart":null,"onloadend":null,"onload":null,"onerror":null,"onabort":null},"withCredentials":false,"readyState":4,"timeout":0,"ontimeout":null,"onprogress":null,"onloadstart":null,"onloadend":null,"onload":null,"onerror":null,"onabort":null}
Any help here would be great, i'm unsure what's causing the error. Seems to work correctly when i'm not passing form data through it. Thanks.
I think you instead should use:
user.setUsername(username);
user.setPassword(password);
Also, these can be combined:
Parse.User.signUp(username, password, { ACL: new Parse.ACL() }, {
success: function (user) {
// Hooray! Let them use the app now.
alert("Success");
},
error: function (user, error) {
// Show the error message somewhere and let the user try again.
alert("Error: " + error.code + " " + error.message);
}
});