Create a blank profile when user signs up - javascript

I know this question has been asked on here once before but I need to know if parse has done anything about it.
My default user table has a pointer field to a UserProfile class.
On signup I have this cloud code below.
Parse.Cloud.beforeSave(Parse.User,async (request)=>{
const user = request.object;
//Making a new Teacherprofile Class
const Objectextension = Parse.Object.extend("TeacherProfile");
const teacherProfile = new Objectextension();
teacherProfile.set("name", "harry");
//Putting teacher profile pointer
user.set("tProfile",teacherProfile);
});
This just dosent not work and results in a timeout.Is there anyway to create the userprofile on before save and associate it to the User Table ? Thanks
UPDATE
This is the working code.
Parse.Cloud.beforeSave(Parse.User,async (request)=>{
const user = request.object;
//if user id does not exists
//it is a new user
if (!user.id) {
//Making a new User Profile Object
const profileObject = Parse.Object.extend("TeacherProfile");
const teacherProfile = new profileObject();
teacherProfile.set("name", "harry");
await teacherProfile.save(null,{ useMasterKey: true });
//Putting teacher profile pointer in user
user.set("tProfile",teacherProfile);
}else{
console.log('old user');
}
});

After a bit more of experimentation I have come to the conclusion that before save is not at all advisable for User Profile Creation.
When signing up lets say the username or email already exists , then the signup does not happen but the profile is saved regardlesss.
So I would advice against it

Or you can use this code.
Parse.Cloud.afterSave(Parse.User, (request) => {
if(!request.original){
//Object saved for first time. This codes will work just first time. And will not work after object saved again.
const user = request.object;
const profileObject = Parse.Object.extend("TeacherProfile");
const teacherProfile = new profileObject();
teacherProfile.set("name", "harry");
await teacherProfile.save(null,{ useMasterKey: true });
//Putting teacher profile pointer in user
user.set("tProfile",teacherProfile);
user.save(null,{useMasterKey:true});
}
});

Related

How to associate a socket.id to an array item?

I'm trying to make a chat-room where connected users' names are displayed in an 'Online Users' section.
The code below will add each users' name to an array and display the contents of the array.
However, if a user leaves, their username isn't removed from the array. If I pop the array, it'll likely not remove the correct username. This makes me think I should, somehow, associate the socket-id with the username given, and create a disconnect event that removes the correct username from the array, and displays the updated version of the array. How could I alter this code to incorporate this?
script.js:
var user = user;
if (!user) {
user = prompt('Please choose a username:');
if (!user) {
alert('Your name has been set to "Anonymous"');
user = "Anonymous"
items.push(user);
} else {
alert('Your name has been set to "'+ user +'"');
}
}
socket.emit('theitems', user);
socket.on('theitems', function (data) {
$('.dispUser').html(data);
console.log(data);
});
server.js:
var newitems = [];
server(socket('theitems', ctx => { newitems.push(ctx.data); console.log(ctx.data); ctx.io.emit('theitems', newitems); }));
I believe that on user connection you update your array of users with new user, something like:
let users = [];
sockets.on('connection', socket) => {
// This is the user associated with a new socket connection.
// User that you will need to remove when connection is closed.
const user = { /* create your user */ };
users.push(user);
// Then you can subscribe to socket disconnect event
socket.on('disconnect', () => {
users = users.filter(u => u !== user); // removing disconnected user
// And then here you can notify your front-end with an updated users array
});
});

Querying users table in Parse Server Cloud returns nothing

I am using Parse Cloud to update user info. The user exists in database. When I query users table it returns nothing. I want to update a field and save it back again. Here is my cloud function:
Parse.Cloud.define("update", async(request) => {
Parse.Cloud.useMasterKey();
let query = new Parse.Query(Parse.User);
query.equalTo("username", "admin");
let user = await query.first();
return user; // now result is empty object {}. but the user exists in database
});
I think this issue relates to permissions because in other cases (other objects) I can query tables without problem.
So when I want to update the name field it says that "user.set is not a function":
if (user) {
user.set("name", "Just a name");
await user.save();
}
Parse.Cloud.useMasterKey(); does not exist for a long time. You should do:
Parse.Cloud.define("update", async(request) => {
let query = new Parse.Query(Parse.User);
query.equalTo("username", "admin");
let user = await query.first({ useMasterKey: true });
return user;
});

How to set Acl for User class in cloud code using before save trigger?

Hello here is my cloud code
Parse.Cloud.beforeSave(Parse.User,async (request)=>{
const user = request.object;
const t = user.get('tProfile');
const s = user.get('sProfile');
if (!t && !s) {
user.setACL(new Parse.ACL(user));
}else{
console.log('Old user detected');
}
});
As you can see I am trying to set Acl for a new user signing up with a before save handler, but the error that I get is UserID must be a string. So my question is how can I set an acl for a new user who is just signing up ? Thankyou
So i finally found a way to do so.
In the Before save handler just use this code :)
Parse.Cloud.beforeSave(Parse.User, async (request) => {
var newOjb = request.object;
if (!request.original) {
newOjb.setACL(new Parse.ACL(Parse.User.current()));
}
});

Firebase Auth: Edit UID

Is it possible to to change a user's UID in Firebase programmatically? There can't seem to be a way to do so manually within Firebase's console.
TL;DR: If you need to specify the UID, you'll need to create a new user with that UID.
You can't directly change the UID, but I was able to hack something together using the firebase admin API (docs)
My use case was that I needed to change a user's email address. I tried update email with "Update a User", but this actually ended up changing the UID under the hood. In my app, the UID is tied to so much stuff, that I'd have to do a huge architecture change, so this wasn't an option.
The general way I did this with the API was:
Pull Down a user using admin.auth().getUserByEmail
Delete the user with admin.auth().deleteUser
Create a new user with admin.auth().createUser, using relevant data from the getUserByEmail call above, replacing the email address with the new email.
"reset password" in the firebase admin console (I think there's a way to do this programmatically too)
User gets an email to reset their password and they have a new account with their old UID.
Unlike admin.auth().updateUser, createUser actually lets you specify a UID.
Building on the answer by RoccoB, the below is a complete set of instructions for changing a user's UID:
Create a new folder, and run npm init with default values.
Run npm install firebase-admin.
Create a NodeJS script file (eg. UpdateUserUID.js), with this code:
let admin = require("firebase-admin");
// config
let email = "XXX";
let serviceAccountData = require("XXX.json");
let adminConfig = {
credential: admin.credential.cert(serviceAccountData),
databaseURL: "https://XXX.firebaseio.com",
};
let newUserOverrides = {
uid: "XXX",
};
Start();
async function Start() {
console.log("Initializing firebase. databaseURL:", adminConfig.databaseURL);
admin.initializeApp(adminConfig);
console.log("Starting update for user with email:", email);
let oldUser = await admin.auth().getUserByEmail(email);
console.log("Old user found:", oldUser);
await admin.auth().deleteUser(oldUser.uid);
console.log("Old user deleted.");
let dataToTransfer_keys = ["disabled", "displayName", "email", "emailVerified", "phoneNumber", "photoURL", "uid"];
let newUserData = {};
for (let key of dataToTransfer_keys) {
newUserData[key] = oldUser[key];
}
Object.assign(newUserData, newUserOverrides);
console.log("New user data ready: ", newUserData);
let newUser = await admin.auth().createUser(newUserData);
console.log("New user created: ", newUser);
}
Replace email and adminConfig.databaseURL with the correct values.
Replace newUserOverrides.uid with the desired new uid. (you can change some other fields too)
Generate/download a private key for your project's Firebase Admin service account: https://firebase.google.com/docs/admin/setup (can skip to the "Initialize the SDK" section)
Update the serviceAccountData variable's import to point to the key json-file from the previous step.
Run node ./UpdateUserUID.js.
If applicable (I didn't seem to need it), use the "reset password" option in the Firebase Admin Console, to have a password-reset email sent to the user, apparently completing the account update. (Perhaps I didn't need this step since I don't use the accounts/authentications for anything besides sign-in on my website...)
The UID of a user is controlled by the identity provider that creates that user. This means that you can't change the UID for any of the built-in providers.
But you can control the UID if you create a custom identity provider. Note that this is quite a bit more involved than changing something in the Firebase console. It requires you to write code that runs in a secure/trusted environment, such as a server you control, or Cloud Functions.
You can't, since is the main tree node of possibles more entries inside it, you can get it, modify and then put it inside the same UID (or create a new one) but you can have things inside, for example take this.
You create your main UID which will hold user data (name, phone, email etc) lets say the structure is this:
-9GJ02kdj2GKS55kg
-Name:
-Phone:
-Email:
so, you can get the main user UID 9GJ02kdj2GKS55kg with mAuth.getCurrentUser().getUid(); and then change it and set a new value inside 9GJ02kdj2GKS55kg, this new value should be the same UID you got but changed, and then inside your main UID you can still have the same structure
-9GJ02kdj2GKS55kg
-6GL02kZj2GKS55kN (this is your changed UID)
-Name:
-Phone:
-Email:
or you can get that changed UID and make a new child, and that will be your parent node with custom UID for the data.
Piggybacking on #Vinrynx's post.
I recently created a migration tool where I am migrating collections from 1 Firebase Project to another and it required that after I insert users to "users" collection I also create an authentication record with the same doc.id
Variables in the functions below:
outCollData : Data that I am inserting for the user (contains the email inside it)
sourceDBApp : output of the admin.initializeApp({/*service-account.json file location for source firebase project */});
destDBApp : output of the admin.initializeApp({/*service-account.json file location for destination firebase project */});
async function updateUsersUID(
outCollData: any,
sourceDBApp: admin.app.App | undefined,
destDBApp: admin.app.App | undefined
) {
if (destDBApp === undefined) return;
const admin = destDBApp;
const email = outCollData.personali.email ? outCollData.personali.email : "";
console.log("Email is ", email);
if (email === "" || email === undefined) return;
console.log("Inside updateUsersUID");
let newUserOverrides = {
uid: outCollData._id,
};
let oldUser: any;
try {
console.log("Starting update for user with email:", email);
oldUser = await admin.auth().getUserByEmail(email!);
//console.log("Old user found:", oldUser);
if (oldUser.uid === outCollData._id) {
console.log(
"User " +
email +
" already exists in the destination DB with UID " +
outCollData._id
);
return;
}
await admin.auth().deleteUser(oldUser.uid);
console.log("Old user deleted.");
} catch (e) {
console.log("User not found in destination DB ", email);
console.log("Copying the user data from source DB");
oldUser = await sourceDBApp?.auth().getUserByEmail(email);
}
let dataToTransfer_keys = [
"disabled",
"displayName",
"email",
"emailVerified",
"phoneNumber",
"photoURL",
"uid",
"providerData",
];
let newUserData: any = {};
for (let key of dataToTransfer_keys) {
newUserData[key] = oldUser[key];
}
Object.assign(newUserData, newUserOverrides);
//console.log("New user data ready: ", newUserData);
let newUser = await admin.auth().createUser(newUserData);
console.log("New user created ");
}

Update document in Mongoose (update array property at specific index)

I'm currently practicing my node.js skills and I am making a top10 movie list on a user's profile page. The user picked ten movies and now I want to save these movies in a user document in my database. This however, isn't working the array is still empty (I was able to change the 'picked' property to true though). Can anyone tell me why? Here is the code on the server side:
router.get('/updateTop10', function (req, res, next) {
// the string that I want to add to the db array
var movieElement = req.query.movieElement;
// the specific index of the array (the position of the movie in the top10
var index = req.query.index;
// the user that is currently logged in
var user = req.user;
User.findOne({'username': user.username }, function (err, user) {
// I am able to switch picked to true
user.top10.picked = true;
// However my array is still empty after I run the code
user.top10.top10[index] = movieElement ;
user.save();
res.send("SUCCESS")
} )
});
This is the structure of the user document:
Refer to https://github.com/Automattic/mongoose/issues/2654
Do this
user.top10.top10.set(index, movieElement);

Categories