|SOLVED| Get User Auth data from Firebase & add it to Firebase DB - javascript

Hello!
EDIT~
I've eventually managed to do this and wanted to share it just in case anyone else needs it. Most tutorials I've found were outdated and none of them seemed to work for me. But I've finally got everything to work so Here it is!
Sign Up -
(I've created a sign up form with input fields for the username, extra info, password and email)
Make sure you import all firebase scripts you want to use and ABOVE all of them, the firebase app main script. In my case I only needed
Auth & Database - And BELOW all of this you put your Firebase App config and import either an
external .js file where you'll be using firebase functions or write it
all down there. This was a very silly mistake I did myself and I kept getting errors on the console. This is because I've been
trying to call my external .js file BEFORE importing the firebase main
scripts, which makes no sense right?
So here's my .js file for the
sign up function:
//On a different .js file where I make use of most of my functions I've added this part
//(just because I've defined more const for all my functions and I wanted to have them all
//in one place):
//getting all elements -- I've only put in this example the ones that I've used for Sign Up
const signupBtn = document.getElementById("btnsignUp");
const txtEmail = document.getElementById('txtEmail');
const txtPassword = document.getElementById('txtPassword');
const userId = document.getElementById('txtName');
const discord = document.getElementById('txtDiscord');
const bday = document.getElementById('txtBday');
const gender = document.getElementById('txtGender');
const imgURL = document.getElementById('txtimgURL');
//getting references to the apps
const auth = firebase.auth();
const database = firebase.database();
const rootRef = database.ref('users');
//------------------------------------------------//
//firebase SIGN UP.js
signupBtn.addEventListener("click", function(){
var email = txtEmail.value;
var pass = txtPassword.value;
//Signing up
auth.createUserWithEmailAndPassword(email, pass)
.then(() => {
//send verification email
sendVerificationEmail();
})
.catch(function(error) {
// Handle Errors here.
//var errorCode = error.code;
var errorMessage = error.message;
alert("Error :" + errorMessage);
});
});
//verification email function
var sendVerificationEmail = () => {
auth.currentUser.sendEmailVerification()
.then(() => {
alert("Verification Email Sent! Check your mailbox.")
})
.catch(error => {
alert("Error :" + errorMessage);
})
}
//DATABASE
//'set' adds new data to he db
signupBtn.addEventListener('click', (e) => {
e.preventDefault();
rootRef.child(userId.value).set({
Email: txtEmail.value,
Discord: discord.value,
Gender: gender.value,
Birthday: bday.value,
ImgURL: imgURL.value,
CC: 0,//Here I've added some more info that's be stored too along with
RS: 0,//the data that the user has provided
Rupreets: 0,
Bag: 1,//1: small, 2: medium, 3: big
})
});
//And that's all!
In my case, what I did with the database part is something like this:
-App name-
|
+--Users:
|
+--username1
|
+-info1
|
+-info2
|
+-info2
|
+--username2
|
+-info1
|
+-info2
|
+-info2
Well, I hope this will help somebody else too n.n

welcome to Stack Overflow!
A couple of things:
You never actually call writeUserData in your code snippet; you just define it. If you don't call it, nothing will be written.
userId is never defined, so even if you called writeUserData, your database path would be be undefined. You'd need to get the userId from firebase.auth().currentUser.uid. For more on that, see this Firebase doc: https://firebase.google.com/docs/auth/unity/manage-users#get_a_users_profile .
-- Edit --
Here's a code sample. I haven't put in absolutely everything, just the relevant omissions:
//Signing up
firebase.auth().createUserWithEmailAndPassword(email, pass)
.then((data) => {
// createUserWithEmailAndPassWord returns a promise, which, when resolved will contain various user-related properties, so
let id = data.User.uid;
function writeUserData(userId, name, email, imageURL) {
firebase.database().ref('Users/' + userId).set({
Username: name,
Email: email,
Profile_pic: imageURL,
});
}
// call your function, referencing the id above
writeUserData(id, name, email, imageURL)
If the idea of promises and calling functions isn't comfortable, you might look at a Javascript learning resource like javascript.info
Good luck!

Related

How can I check if a firebase Reference is empty before fetching it?

I'm trying to fetch a specific document from firebase. If it exists, great. But if it doesn't, I don't want it to break my app. I just want it to move on. However, I can't seem to shake off this error:
my error
Here is my code:
async function getOtherInfo() {
//get profile image, username if they exist
const profileRef = doc(db, "profiles", email);
const snap = await getDoc(profileRef);
if (snap.exists()) {
setProfileImg(snap.data().profileImg);
setUserName(snap.data().userName);
}
Firebase gurus, please help me, I'm going crazy soon. Thanks a bunch.
edit: added code sections to show where my db and email state is coming from. Both are valid.
//init services
const db = getFirestore();
const [email, setEmail] = useState(identifier.email)
If think you'r looking for:
if (email) { // 👈
//get profile image, username if they exist
const profileRef = doc(db, "profiles", email);
const snap = await getDoc(profileRef);
if (snap.exists()) {
setProfileImg(snap.data().profileImg);
setUserName(snap.data().userName);
}
This ensure that you only try to load the document if there actually is an email value.

ETH ENS Web3 - How to get Registrant

I've following code snippet to get the "Controller" (The owner of the domain) but I need to get the "Registrant" of provided ENS name
const Web3 = require("web3")
const web3 = new Web3("https://cloudflare-eth.com");
var ens = web3.eth.ens;
var names = ['jtimberlake.eth', 'usman.eth'];
(async () => {
for (let domainName of names) {
// console.log('checking: ' + domainName);
const addr = await getDomain(domainName);
console.log(addr);
}
})();
async function getDomain(word) {
try {
const addr = await ens.getAddress(`${word}`)
// console.log(addr);
return addr;
} catch (err) {
console.error(err);
return;
}
}
Can you please guide how I can get the "Registrant" of provided ENS name e.g. jtimberlake.eth
Web3 is a steaming pile. It doesn't do it with its methods. The registrant used to be called the deed owner, and the controller the owner. Now it is registrant and controller. That's why the method name makes no sense at all now in Web3.js - it never got updated, and never was useful for this in the first place.
The good news is there is a simple way. You can derive the token ID of the ENS domain from its name with the getRegistrant function below. https://docs.ens.domains/dapp-developer-guide/ens-as-nft
The name variable in the docs is superfluous and does nothing. You will need to instantiate ethersjs (npm install ethers) to get the ethers methods to work. You have to use this crazy number of functions because the token ID of an ENS domain/NFT is a uint256. JavaScript hates those natively.
The web3 method to find the controller also still works well if you ever need that. I suggest putting it in another function.
const getRegistrant = (domainName) => {
const BigNumber = ethers.BigNumber
const utils = ethers.utils
const labelHash = utils.keccak256(utils.toUtf8Bytes(domainName))
const derivedTokenId = BigNumber.from(labelHash).toString()
//You need to instantiate the ENSRegistrarContract with its ABI and address. e.g. const ENSRegistrarContract = new web3.eth.Contract(ABI, ADDRESS)
ENSRegistrarContract.methods.ownerOf(derivedTokenId).call()
.then(function(registrant) {
console.log(domainName + "is owned by: " + registrant)
return registrant
})
}
const getController = (domainName) => {
//getOwner fetches the controller of a domain confusingly.
web3.eth.ens.getOwner(domainName).then(function(controller) {
console.log(domainName + "is controlled by: " + controller)
return controller
})
}

Cloud Function is not running - React Native

I'm new to React Native and I have an issue with Cloud Functions.
getAuthor(uid){
var getUser = firebase.functions().httpsCallable('getUser');
console.log('success');
getUser({uid: uid}).then(function(result) {
console.log('getUser called')
var user = result.data.uid;
return(
result
)
})
.catch(function(error) {
var code = error.code;
var message = error.message;
var details = error.details;
});
}
When I run this code, 'success' is printed but 'getUser called' is never printed. I take this to mean getUser is never called. But I have followed the Firebase guide 'Call functions from your app' and it seems to be the same. Is it a problem with Cloud Functions never being initialised or something? In the Firebase guide it says to initialise an instance of Cloud Functions by adding
var functions = firebase.functions();
but when I added it to config.js I got an error so I skipped this step. Sorry if this seems obvious, I have never used React Native or Firebase before. Any help would be greatly appreciated!
Edit: the function has been deployed, as can be seen in this screenshot
This is the function, by the way:
exports.getUser = functions.https.onCall((data, context) => {
const uid = data.uid;
auth.getUser(uid)
.then(function(UserRecord) {
console.log('USER RECEIVED:' + UserRecord.email.toJSON());
return {email : UserRecord.email.toJSON()};
})
.catch(function(error){
console.log(error);
});
Turns out I can't access user information with their UID! The solution is to add it into Firebase Database instead.

AWS managing users via Cognito

I have used many services from AWS, some were easy, while some were a bit difficult. After 2 days of searching everywhere, I can say documentation for this service is misleading.
I have simple task to do. I want to change a user attribute in the Cognito pool. And to make things easy, I just need to change an Email, and thats it. Application is an Backoffice (Express/Node), where admins can change user's email.
After reading and reading, I am getting more confused. Apparently, the aws-sdk library, the one I am familiar with, has some Cognito API's that I could use. Getting a working example on how to use them, turned out to be a nightmare.
Then I found out there is a library, but only to be used on the client side. After some tweaks I got it running in Node.js. The tweak was to expose a fetch library in global Node.js namespace.
I was able to add a new user. But for all my intentions, I can't change any of the attributes (like email). The library wants me to provide Username (real user) and a password.
I do have a Username (in this case an email), but I don't have the password.
All I need to do is to connect to the service, and send new attribute for the user and thats it.
This is what I have so far (mainly hacked code samples, from variety of places), and I cant get it to work:
var poolData = {
UserPoolId : 'euXXXXXXX',
ClientId : 'XXXXXXXXXXXX'
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
Ok The above line makes a connection to the existing user pool.
Now if I were to do this:
var attributeList = [];
var dataEmail = {
Name : 'email',
Value : 'email#mydomain.com'
};
var dataPhoneNumber = {
Name : 'phone_number',
Value : '+15555555555'
};
var attributeEmail = new AmazonCognitoIdentity.CognitoUserAttribute(dataEmail);
var attributePhoneNumber = new AmazonCognitoIdentity.CognitoUserAttribute(dataPhoneNumber);
attributeList.push(attributeEmail);
attributeList.push(attributePhoneNumber);
userPool.signUp('username', 'password', attributeList, null, function(err, result){
if (err) {
alert(err.message || JSON.stringify(err));
return;
}
cognitoUser = result.user;
console.log('user name is ' + cognitoUser.getUsername());
});
I can see in AWS console that the user is being added. Great.
Now how to change the attributes of the existing user?
All of examples like this and this
Suggest the following:
Use case 8. Update user attributes for an authenticated user.
var attributeList = [];
var attribute = {
Name : 'nickname',
Value : 'joe'
};
var attribute = new AmazonCognitoIdentity.CognitoUserAttribute(attribute);
attributeList.push(attribute);
cognitoUser.updateAttributes(attributeList, function(err, result) {
if (err) {
alert(err.message || JSON.stringify(err));
return;
}
console.log('call result: ' + result);
});
The problem here is I cant authenticate the user. I can't know user's password, only his email. This is after all a simple Backoffice program, where I just need to change users email.
What can I do in this case?
To update the attributes of a Cognito User Pool-user as an admin, you should use adminUpdateUserAttributes function from the aws-sdk class CognitoIdentityServiceProvider.
let AWS = require('aws-sdk');
let cognitoISP = new AWS.CognitoIdentityServiceProvider({ region: 'your-region-here' });
function updateUserAttribute(name, value, username, userPoolId){
return new Promise((resolve, reject) => {
let params = {
UserAttributes: [
{
Name: name, // name of attribute
Value: value // the new attribute value
}
],
UserPoolId: userPoolId,
Username: username
};
cognitoISP.adminUpdateUserAttributes(params, (err, data) => err ? reject(err) : resolve(data));
});
}

firebase add user to realtime database upon sign up (javascript)

I'd need to create a users main node, that will have as child users id created upon sign up, as well as child elements dynamically populated later on (empty for now).
so my db would look like:
- users
- uid
- lists
- list name
- content
- uid
- uid
...
I'm still at the beginning and for now i'm trying to put the user id inside - users but doesn't work, the code (EDITED):
var refUsers = database.ref('users');
// Add sign up event
btnSignup.addEventListener('click', e => {
// to do: check for real email
const email = txtEmail.value;
const pass = txtPassword.value;
const auth = firebase.auth();
// Sign in
auth.createUserWithEmailAndPassword(email, pass)
.then(function success(userData){
var uid = userData.uid;
refUsers.push(uid);
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
alert('Error: ' + errorMessage);
});
});
I also didn't understand if i should manually or programmatically create the main - users node inside the database, how (since it asks me for a value too) so for now i didn't create it at all, the documentation lack of many stuff imo.
The functionality you're describing can be achieved using Firebase Authentication Triggers.
ie.
const database = firebase.database()
const createUser = user => database.ref().child(`User/${user.uid}`).set(user)
exports.createUser = functions.auth.user().onCreate(createUser)

Categories