Custom Uid In Firebase CreateUser - firebase

My app structure requires me to log in user with a specific Uid.
Can i do that in Firebase Auth.
I mean , If i want to create a user with uid=1.
which i will send along with email and password.
Is it possible ?

Yes, you can with admin sdk:
admin
.auth()
.createUser({
uid: 'some-uid',
email: 'user#example.com',
phoneNumber: '+11234567890',
})
.then((userRecord) => {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully created new user:', userRecord.uid);
})
.catch((error) => {
console.log('Error creating new user:', error);
});

You can set UID for the Firebase user if you use a custom token to authenticate.
See this https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_a_third-party_jwt_library
Here's the example using Ruby (:uid => uid)
require "jwt"
# Get your service account's email address and private key from the JSON key file
$service_account_email = "service-account#my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."
def create_custom_token(uid, is_premium_account)
now_seconds = Time.now.to_i
payload = {:iss => $service_account_email,
:sub => $service_account_email,
:aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
:iat => now_seconds,
:exp => now_seconds+(60*60), # Maximum expiration time is one hour
:uid => uid,
:claims => {:premium_account => is_premium_account}}
JWT.encode payload, $private_key, "RS256"
end

There is a way to create custom uids with the admin SDK, but I'm not sure about the username/password part: https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_the_firebase_admin_sdk
const uid = 'some-uid';
admin
.auth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});

Related

Registration token(s) provided to sendToDevice() must be a non-empty string or a non-empty array. (Firebase cloud functions)

I am making a chat application where I am trying to send push notifications to when one user sends a message to the other user.
I am using firebase cloud functions with JavaScript and in the firebase functions log I can see that it's able to get the user who sends the message and the user who receives the message. But for some reason It's showing me that the token is empty.
Even though I have a token and I am able to print it in the log(The screenshot of firebase cloud functions log where you can see that token is being printed and I have partially marked over it).
For more reference I am also attaching the screenshot of my two collections in firebase -
All the users collection where the push token is being saved.(The structure is users>uid>{user_info}).
The chat collection screenshot where you can see the structure of chats.(The structure here is chatroom>chatid>chats>{chat_documents}).
My index.js file in functions folder for firebase is below-
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()
exports.sendNotification = functions.firestore
.document('chatroom/{chatId}/chats/{message}')
.onCreate((snap) => {
console.log('----------------start function--------------------')
const doc = snap.data()
console.log(doc)
const idFrom = doc.idFrom
const idTo = doc.idTo
const contentMessage = doc.mesaage
console.log(`Starting to push token`)
// Get push token user to (receive)
admin
.firestore()
.collection('users')
.where('uid', '==', idTo)
.get()
.then(querySnapshot => {
querySnapshot.forEach(userTo => {
console.log(`Found user to: ${userTo.data().name}`)
console.log(`Found user to: ${userTo.data().pushtoken}`)
try {
// Get info of the user who is sending the message
admin
.firestore()
.collection('users')
.where('uid', '==', idFrom)
.get()
.then(querySnapshot2 => {
querySnapshot2.forEach(userFrom => {
console.log(`Found user from: ${userFrom.data().name}`)
const payload = {
notification: {
title: `"${userFrom.data().name}"`,
body: contentMessage,
badge: '1',
sound: 'default'
}
}
// Lets push to the target device
admin
.messaging()
.sendToDevice(payload,userTo.data().pushtoken)
.then(response => {
console.log('Successfully sent message:', response)
})
.catch(error => {
console.log('Error sending message:', error)
})
})
})
} catch(e){
console.log('Can not find pushToken target user')
}
})
})
return null
})
What might be the problem here as I am not able to figure it out? Your help would be really appreciated. Also kindly let me know if you want any more information regarding the same.

Delete auth user in firebase react native

I am trying to delete auth user from firebase with email or uid. I searched on google but I did not find any solution.
There is a code section:
getAuth()
.deleteUser(uid)
.then(() => {
console.log('Successfully deleted user');
})
.catch((error) => {
console.log('Error deleting user:', error);
});
Additionally reference link: https://firebase.google.com/docs/auth/admin/manage-users#delete_a_user
I found this method, but this deletes current user, I want to delete the specific user.
import { getAuth, deleteUser } from "firebase/auth";
const auth = getAuth();
const user = auth.currentUser;
deleteUser(user).then(() => {
// User deleted.
}).catch((error) => {
// An error ocurred
// ...
});
For React Native
import auth from "#react-native-firebase/auth";
let user = auth().currentUser;
user
.delete()
.then(() => console.log("User deleted"))
.catch((error) => console.log(error));

How to delete unverified e-mail addresses in Firebase Authentication/Flutter?

After registering with Firebase Authentication "Email / Password",saving e-mail without verification.I have application with Flutter firebase. When someone registers, I direct them to an email verification page and hold them there until they verify the email.The problem is that if someone uses my email and deletes app without verifying it, the mail still remains in the database.How do we delete unverified email addresses?
You can run a scheduled cloud function every day that checks for unverified users and deletes them. That also means you would have to use Admin SDK and cannot be done in Flutter. You can create a NodeJS Cloud Function with the following code and run it.
exports.scheduledFunction = functions.pubsub.schedule('every 24 hours').onRun((context) => {
console.log('This will be run every 24 hours!');
const users = []
const listAllUsers = (nextPageToken) => {
// List batch of users, 1000 at a time.
return admin.auth().listUsers(1000, nextPageToken).then((listUsersResult) => {
listUsersResult.users.forEach((userRecord) => {
users.push(userRecord)
});
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
}
}).catch((error) => {
console.log('Error listing users:', error);
});
};
// Start listing users from the beginning, 1000 at a time.
await listAllUsers();
const unVerifiedUsers = users.filter((user) => !user.emailVerified).map((user) => user.uid)
//DELETING USERS
return admin.auth().deleteUsers(unVerifiedUsers).then((deleteUsersResult) => {
console.log(`Successfully deleted ${deleteUsersResult.successCount} users`);
console.log(`Failed to delete ${deleteUsersResult.failureCount} users`);
deleteUsersResult.errors.forEach((err) => {
console.log(err.error.toJSON());
});
return true
}).catch((error) => {
console.log('Error deleting users:', error);
return false
});
});
You can delete users through the Firebase Admin SDK.
You'll need a list of unverified users, either by listing all users and filtering it down, or from somewhere you store this yourself, and then you can delete the unverified users.
This works just perfect:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.scheduledFunction = functions.pubsub
.schedule("every 24 hours")
.onRun((context) => {
console.log("This will be run every 24 hours!");
var users = [];
var unVerifiedUsers = [];
const listAllUsers = async (nextPageToken) => {
// List batch of users, 1000 at a time.
return admin
.auth()
.listUsers(1000, nextPageToken)
.then((listUsersResult) => {
listUsersResult.users.forEach((userRecord) => {
users.push(userRecord);
});
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
}
})
.catch((error) => {
console.log("Error listing users:", error);
});
};
// Start listing users from the beginning, 1000 at a time.
listAllUsers().then(() => {
unVerifiedUsers = users
.filter((user) => !user.emailVerified)
.map((user) => user.uid);
admin
.auth()
.deleteUsers(unVerifiedUsers)
.then((deleteUsersResult) => {
console.log(
`Successfully deleted ${deleteUsersResult.successCount} users`
);
console.log(
`Failed to delete ${deleteUsersResult.failureCount} users`
);
deleteUsersResult.errors.forEach((err) => {
console.log(err.error.toJSON());
});
return true;
})
.catch((error) => {
console.log("Error deleting users:", error);
return false;
});
});
});

Using vuex, firestore, and createUserWithEmailAndPassword, how do I create a user profile collection when a user registers?

For the app I'm building, I want my users to have a profile created for them when they register; the profile would contain the user's username, email, and the uid created by firebase authentication. I've got the authentication portion using createUserWithEmailAndPassword to work on its own. I'm also able to create a "users" collection, capturing a username and the user's email, on its own as well. However, I'm running into trouble grabbing and saving the uid to the user's profile in the user's collection.
Here is the code I have at the moment:
import * as firebase from "firebase/app";
import db from "../../components/firebase/firebaseInit";
actions: {
registerUser({ commit }, payload) {
commit("setLoading", true);
commit("clearError");
firebase
.auth()
.createUserWithEmailAndPassword(payload.email, payload.password)
.then(user => {
commit("setLoading", false);
const newUser = {
email: user.email,
id: user.uid,
courses: []
};
commit("setUser", newUser);
db.collection("users")
.add({
username: payload.username,
email: user.email,
userId: user.uid
})
.then(() => {
console.log("New user added!");
})
.catch(err => {
console.log(err);
});
})
.catch(err => {
commit("setLoading", false);
commit("setError", err);
});
},
In the research I've done, I've found these suggested solutions:
Get Current User Login User Information in Profile Page - Firebase and Vuejs
Cloud Firestore saving additional user data
And this video:
https://www.youtube.com/watch?v=qWy9ylc3f9U
And I have tried using the set() method instead of add(), as well.
But none of them seem to work, for me at least.
Thank you in advance for your help.
And if you need to see any more code, just let me know.
You haven't shared the error message you get, but most probably the error comes from the fact that the createUserWithEmailAndPassword() method returns a UserCredential and not a User.
So you have to do as follows:
import * as firebase from "firebase/app";
import db from "../../components/firebase/firebaseInit";
actions: {
registerUser({ commit }, payload) {
commit("setLoading", true);
commit("clearError");
firebase
.auth()
.createUserWithEmailAndPassword(payload.email, payload.password)
.then(userCredential=> {
commit("setLoading", false);
const user = userCredential.user; // <-- Here is the main change
const newUser = {
email: user.email,
id: user.uid,
courses: []
};
commit("setUser", newUser);
return db.collection("users")
.add({
username: payload.username,
email: user.email,
userId: user.uid
});
})
.then(() => {
console.log("New user added!");
})
.catch(err => {
commit("setLoading", false);
commit("setError", err);
});
},

Creating a new user via Firebase Cloud Functions - account created but can not sign in

I am new here.
I am currently developing an app using Vue.js with firebase auth, firebase realtime database and firebase cloud functions as a backend. One part of the functionalities that the app has to include an admin account that has a possibility to create an accounts for other people. After creation new user receives an email with a login and a password to log in.
Because the signing up method (https://firebase.google.com/docs/auth/web/password-auth) automatically relog user to a newly created account which is obviously not wanted behavior I found a way to create a user via cloud functions. The code successfully creates an account in the firebase authentication panel with the exception that I cannot log in to the newly created accounts. I get a message that: "The password is invalid or the user does not have a password".
Additionally I am not sure if it means anything in this case but the accounts created with the cloud functions method does not have a mail icon in firebase authentication panel (Image).
Cloud Function Code:
exports.createUser = functions.https.onCall((data, context) => {
console.log(data)
return admin.auth().createUser({
email: data.email,
emailVerified: true,
password: data.password,
displayName: data.email,
disabled: false,
})
.then(user => {
return {
response: user
}
})
.catch(error => {
throw new functions.https.HttpsError('failed to create a user')
});
});
Sign In Code:
signIn: async function(){
if(this.email && this.password){
let getUsers = firebase.functions().httpsCallable('getUsers')
this.feedback = null
this.spin = true
let destination = null
let logedUser = null
let type = null
this.feedback = 'Logging in...'
await firebase.auth().signInWithEmailAndPassword(this.email, this.password)
.then(response => {
this.feedback = 'Authorization finished...'
logedUser = response.user
})
.catch( error => {
this.feedback = error.message
this.spin = false
})
//... more code here but I am certain it has nothing to do with the problem.
Due to the asynchronous character of the HTTPS callable function, with your current code you are trying to sign-in before the user is completely created through the Cloud Function.
In addition, you are actually not calling the Cloud Function with the mail and password parameters.
You should do as follows, based on the documentation.
....
let getUsers = firebase.functions().httpsCallable('getUsers')
await getUsers({email: this.email, password: this.password})
.then(result => {
return firebase.auth().signInWithEmailAndPassword(this.email, this.password)
})
.then(userCredential => {
this.feedback = 'Authorization finished...'
logedUser = userCredential.user
return true
})
.catch( error => {
this.feedback = error.message
this.spin = false
})
....

Resources