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)
Related
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.
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!
I'm sending data from a form to my database. As I've understood correctly, using .push() creates a unique ID where my data is appended to and uploaded. I need to now get that same data and then add a new ID entry. But I can't reference the data since its stored under the unique ID created by the .push() method.
exports.addUser = functions.https.onRequest(async (req, res) => { //Adds data from the form to the database
cors(req, res, async () => {
// Grab the message body parameter.
const entry = req.body;
// Push the new message into the Realtime Database using the Firebase Admin SDK.
const snapshot = await admin.database().ref('entries/users/').push(entry);
console.log('my new shiny id is ' + snapshot.key());
// Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
res.redirect(303, snapshot.ref.toString());
})
});
//Function to generate a random ID and update into the entry from the form on the database.
exports.generateID = functions.database.ref('entries/users/').onCreate((snapshot, context) => {
console.log(snapshot.val());
const original = snapshot.val();
console.log(context);
console.log(snapshot.key());
const dev = '0eeb94ca-3426-46ca-964d-a9bdd7d00ef0';
var random = Math.random().toString(36).substring(7);
const code = uuidv5('user-' + random, dev);
return snapshot.ref.update({
userID: code
});
})
Here is an image of the data structure in my real-time database.
I think you meant to use a wildcard in your function in order to capture that ID (and also trigger on only that new node):
functions.database.ref('entries/users/{id}').onCreate((snapshot, context) => {
Now you can use context.params.id to get that ID, and write more easily under that new node.
All I needed to do was pass in a parameter into my ref url.
exports.addUser = functions.https.onRequest(async (req, res) => { //Adds data from the form to the database
cors(req, res, async () => {
// Grab the message body parameter.
const entry = req.body;
// Push the new message into the Realtime Database using the Firebase Admin SDK.
const snapshot = await admin.database().ref('entries/users/').push(entry);
console.log('my new shiny id is ' + snapshot.key());
// Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
res.redirect(303, snapshot.ref.toString());
})
});
//Function to generate a random ID and update into the entry from the form on the database.
exports.generateID = functions.database.ref('entries/users/{id}').onCreate((snapshot, context) => {
const dev = '0eeb94ca-3426-46ca-964d-a9bdd7d00ef0';
var random = Math.random().toString(36).substring(7);
const code = uuidv5('user-' + random, dev);
return snapshot.ref.update({
userID: code
});
})
The {id} will stand as a parameter for the ID created by the .push() method. The function will update the data entry with the generated ID.
So I am trying to send a notification via Functions on Firebase.
I am doing the notification programming on JavaScript via Node.js.
Upon clicking Send Friend Request from one account, the other person is suppose to get a notification as specified on the payload of the JavaScript file I have attached below.
I keep getting the following error on my Firebase Functions
ReferenceError: event is not defined.
Here is an image of the exact error.
Here is my JavaScript file:
/*
* Functions SDK : is required to work with firebase functions.
* Admin SDK : is required to send Notification using functions.
*/
//This runs JavaScript in Strict Mode, which prevents the use of things such as undefined variables.
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
/*
* 'OnWrite' works as 'addValueEventListener' for android. It will fire the function
* everytime there is some item added, removed or changed from the provided 'database.ref'
* 'sendNotification' is the name of the function, which can be changed according to
* your requirement
*/
exports.sendNotification = functions.database.ref('/Notifications/{retrieveUserId}/{notificationId}').onWrite((data, context) => {
/*
* You can store values as variables from the 'database.ref'
* Just like here, I've done for 'user_id' and 'notification'
*/
const retrieveUserId = context.params.retrieveUserId;
const notificationId = context.params.notificationId;
console.log('User id is : ', retrieveUserId);
//Prevents notification being sent if there are no logs of notifications in the database.
if (!event.data.val()) {
return console.log('A notification has been deleted from the database : ', notificationId);
}
const deviceToken = admin.database().ref(`/Users/${retrieveUserId}/device_token`).once('value');
return deviceToken.then(result => {
const tokenId = result.val();
const payload = {
notification: {
title: "Friend Request",
body: "You have received a friend request from Slim Shady",
icon: "default"
}
};
return admin.messaging().sendToDevice(tokenId, payload).then(response => {
return console.log('Notification was sent to the user');
});
});
});
This is a picture of parents and children of my Firebase database referred to in the JavaScript file.
As the error states an event not being defined, I'm trying to figure out which event I have not defined.
What is the issue here?
You have not defined event in this code block:
if (!event.data.val()) {
I'm currently using Firebase such that users sign in with their Google accounts to access the app. However, closing the page/opening the page in a new tab requires the user to sign in again. Is there a way to prevent users from having to re-login?
Here is the login code I am using (the example from the firebase docs)
function firebaseLogin() {
firebase.auth().signInWithPopup(provider).then(function(result) {
var token = result.credential.accessToken;
var user = result.user;
document.getElementById('user-name').innerHTML = user.displayName;
document.getElementById('propic').src = user.photoURL;
addClass(login, 'hidden');
removeClass(logout, 'hidden');
var snackbarData = {
message: 'Login Successful',
timeout: 2000
};
snackbarContainer.MaterialSnackbar.showSnackbar(snackbarData);
console.log(user);
reloadList();
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential;
var snackbarData = {
message: 'Login Unsuccessful',
timeout: 2000
};
snackbarContainer.MaterialSnackbar.showSnackbar(snackbarData);
console.error(error);
});
}
I'm not sure if this is the official way to do it, but I ended up saving the user returned from firebase.auth().currentUser in localStorage, and then checking if a user could be found in localStorage on document load. If a user is found, I just set firebase.auth().currentUser to equal the user from localStorage, and everything seemed to work as intended. (For example, if there wasn't an authenticated user, the client wouldn't be able to make calls to the database, but setting currentUser in this fashion allowed accessing the database.)