Here is the Parse javascript cloud code I am trying to use. As a new _User is created I want to add them to my 'Client' Role.
Parse.Cloud.afterSave(Parse.User, function(request) {
Parse.Cloud.useMasterKey();
query = new Parse.Query(Parse.Role);
query.equalTo("name", "Client");
query.first ({
success: function(role) {
role.getUsers().add(request.user);
role.save();
},
error: function(error) {
throw "Got an error " + error.code + " : " + error.message;
}
});
});
This is taking code directly from Parse.com's Role example. The code runs happily when a new _User is saved, returning Result: Success, but when I check the "users" tied to that Role in the Data Browser, nothing has happened.
I have also tried substituting role.getUsers().add(request.user); for role.relation("users").add(request.user); as per an example on Parse.com's old forum, but no difference. This seems like it should be really straight forward, so I'm not sure what I'm doing wrong.
(I have manually used the REST API, using curl, to add _Users to the Client Role, and this does work, so I know it should work.)
Turns out you need to use request.object instead of request.user. Now it works!
Related
I am uploading images to firebase storage and would like to save their images as the photoURL in Firebase authentication. However when I go to upload the image URL after using get signed URL I receive the error
Error: The photoURL field must be a valid URL.
I know that the URL is valid as I have checked it from the console out put. I have tried using decodeURI and even gone so far as to look into the source code for the firebase-admin-node tracking all the way down to a file called auth-api-requests.ts which on line 252 checks the URL in a function named validator.isURL(request.photoUrl) this led me to the file where the function is defined validator.ts which defines .isURL() on line 152 in this function checks are performed against a string of forbidden characters. I dont want to tamper with the Firebase source code, but I am unable to find any solution. There should be an easier solution for the return from one google function .getSignedURL() to be used as a parameter in another .updateUser({photoURL:}) especially considering that one can no longer call on firebase.getDownloadURL() from the google cloud functions node. Thank you for any assistance you provide in solving this.
var downloadURL = "";
await admin.storage().bucket("gs://****firebase.appspot.com").file(storageRef).getSignedUrl({"action":"read","expires":Date.now() + 500*365*24*3600000}).then((value) => {
console.log("value after requesting signed URL: " + JSON.stringify(value));
downloadURL = value;
return value;
}).catch((error) => {
console.log("error perfoming signed URL: " + error);
return error;
})
const url = decodeURI(downloadURL)
console.log("\nThe decodeURI url: " + url + "\n");
await admin.auth().updateUser(userID,{photoURL:url}).then((user) => {
console.log("User update ran a success: " + JSON.stringify(user));
return true;
}).catch((error) => {
console.log("An error occured in getting the user: " + error);
return error;
});
It is not a good idea to hard code the users photoURL (which is only populated for federated sign in users) as it may change. In other words, a Twitter user might change their profile photo. firebase.auth() provides you fresh user metadata upon user sign in.
It only adds maintenance overhead to save this type of metadata - there's no need to bother with this.
You should use the Authenticated URL which is definitely a valid URL, instead of the gsutil URI - gs://~
https://storage.cloud.google.com/${PROJECT_ID}.appspot.com/${pathToFile}
I'm trying to update one of my subscriber's status using mailchimp API 3.0, Meteor and javascript.
Here is my js code I'm using:
request({
uri,
list_id,
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': 'apikey (my api key)'
},
json,
}, function(err, res, body) {
if (err) {
return console.log("err:", err);
}
console.log("connection succeed");
console.log("res: ", res.body);
console.log("body: ", body);
});
with
uri = "https://us15.api.mailchimp.com/3.0/lists/" + (id of my list) + "/members/" + (md5 of my user mail);
and
json = {
"email_address": (user mail as a string),
"status": "unsubscribed"
};
But I always have the same output:
I20181204-18:42:12.714(8)? title: 'Member Exists',
I20181204-18:42:12.714(8)? status: 400, I20181204-18:42:12.714(8)? detail: '(user mail adress) is already a list member. Use PUT
to insert or update list members.'
But I am using PUT already... The request works with POST if it's the first time I add the user. But now I can't update my user status...
Is something wrong with my request or with the way I use the API? Thanks in advance.
EDIT 1 -> trying with GET doesn't work. The request itself is correct but it has no effect on my subscriber's status. So I still need to make PUT work.
After looking at the official doc in the "Edit" tab, I found the answer!
The json required another mandatory parameter and should look like this:
json = {
"email_address": (user mail as a string),
"status_if_new": "unsubscribed",
"status": "unsubscribed"
};
I know that this is an older question but I just wanted to add something in the event that it helps someone.
I was having a similar issue intermittently with most of my PUT requests working as expected and some not.
It took me a while but eventually I figured out that some of my email addresses had spaces at the end.
This error would result.
Trimming the addresses before doing anything resolved my issue.
I am using AWS Cognito to authenticate users in a new app that I am building.
I am using the amazon-cognito-identity-js library in my project (link to Github: https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js). Since users in this particular user pool cannot sign themselves up - I sign them up manually - I know that I need "Use case 23" as stated in the README.md from Github.
So my code is as follows:
...
const userPoolData = {
UserPoolId: <MY_USER_POOL_ID>,
ClientId: <MY_CLIENT_ID>
};
const userPool = new CognitoUserPool(userPoolData);
const authenticationData = {
Username: email,
Password: tempPassword
};
const userData = {
Username: email,
Pool: userPool
}
const authenticationDetails = new AuthenticationDetails(authenticationData);
const cognitoUser = new CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
console.log(result);
},
onFailure: (err) => {
console.log("Error from cognito auth: ", err);
},
newPasswordRequired: (userAttributes) => {
delete userAttributes.email_verified;
cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
}
})
...
When I execute this code, I successfully confirm my user. I can see this in the AWS Cognito console. However, instead of receiving the result object, I get an error in the javascript console on the client that says:
Uncaught (in promise) TypeError: Cannot read property 'onFailure' of undefined
at eval (CognitoUser.js:572)
at eval (Client.js:108)
But when I attempt to sign in with the newPassword in place of the tempPassword previously sent, I am now able to successfully get the resultobject with the three tokens all present.
So I know that everything is kinda working, but isn't what I am expecting.
What is causing this error? How can I fix it? I want to receive the result object immediately when the user first signs in with the tempPassword and their newPassword so that they can start using the app.
EDIT:
Thinking that I had to retrieve the userAttributes myself was a mistake. The newPasswordRequired function passes them automatically. So I updated my code above to go with "Use case 23" as presented on Github.
But now I get a slightly different error than before:
Uncaught (in promise) TypeError: callback.onFailure is not a function
at eval (CognitoUser.js:572)
at eval (Client.js:108)
Everything still works as far as Cognito is concerned, but there must be something wrong with my onFailure function, which is very strange.
Any thoughts?
Thanks in advance
Alright, I solved it. The issue was that I was using ES6 arrow functions. As Apolozeus pointed out, I needed to pass this into the cognitoUser.completeNewPasswordChallenge function. But due to the way ES6 behaves, this was returning undefined. So, changing my cognitoUser.authenticateUser function to the following solved everything:
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
resolve(result.getAccessToken().getJwtToken());
},
onFailure: function (err) {
console.log("Error from cognito promise: ", err);
reject(err);
},
newPasswordRequired: function (userAttributes) {
delete userAttributes.email_verified;
cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
}
})
I'm going to play around with the amazon-cognito-identity-js library a bit and see if I can get ES6 arrow functions to work here. It's really annoying to have to work around that.
Shout out to Apolozeus for the help
Please update the line cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes); into cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this) Basically, this will make sure the callback function within the same object.
I am trying to build a simple background job on the Parse Cloud. Right now, I'm just testing, but I am having a problem when performing a query.
If I comment out:
//query.ascending("createdAt");
the console log shows all the messages and no errors. If I don't comment it out, I get an error. Can anybody explain why this is happening? Is it an authentication error?
Parse.Cloud.job("cleanPosts", function(request, status) {
var Post = Parse.Object.extend("Post");
var query = new Parse.Query(Post);
query.ascending("createdAt");
query.each(function(post) {
console.log( "objectId:" + post.get("message") );
}).then(function() {
status.success("Success");
}, function(error) {
status.error();
});
});
When using Parse.Query.each, you do not need to (and cannot) provide an orderBy. It will run the callback for every object (actually ordered by objectId).
The official error is "Cannot iterate on a query with sort, skip, or limit." and it should appear if you log that in the error block.
I'm using javascript and parse.com
The below section of code should query the parse.com back end and look for users that exist called "Rob". When inspecting it using Chrome dev tools no errors are returned to the console.
However the code always completes successfully, even using the example shown where I know that there is not a user called "Rob" stored in that parse object.
I dont understand what I'm missing in my code or why it wont error if the user does not exist?
var friendFinder = Parse.Object.extend("_User");
var query = new Parse.Query(Parse.User);
query.equalTo("username", "Rob"); // find users that match
query.find({
success: function(results) {
console.log("Yay");
},
error: function (contact, error) {
//Show if no user was found to match
alert("Error: " + error.code + " " + error.message);
}
})
;
Not finding a row is not an error condition. The result of the call was successful, and your results were empty.