firebase - if statement not executed after query - javascript

I have integrated firebase in a vue app. I have a navbar that can show some user informations like name and status, and I need to query firebase realtime database after the login to set the needed informations inside my store that will manage application state.
I'm using this code when the navbar component is mounted but the if() statement will be not executed. The strange thing is that I'm able to log each user during the loop. Is there something wrong or another solution to achive this?
onValue(query(ref(db, 'Users'), orderByKey('uid')), users => {
users.forEach( (user) => {
let userData = user.val()
// the console will log each user correctly
console.log(userData)
if( userData.uid == store.currentUser.uid ) {
console.log('called')
console.log(userData)
}
})
})

Related

How to fetch a single data value out of firebase database with reactjs

Im working on a project trying to fetch a name of the current user that is logged in.
When we create a user its getting added in the database with a unique id as row name.
Here you can see all the users that are registered but i only want the one that is logged in so i can pick the first and last name to say "Hello (bla) (bla)"
The code i have now it this :
import React from "react"
import { auth, database } from '../../handlers/Firebase'
export default function Dashboard() {
const user = auth.currentUser
const refUserInformation = database.ref('UserInformation/')
refUserInformation.on('value', function(data){
console.log(data.val())
})
return (
<div className="page-dashboard">
<div className="maxtext">
<p>userid: {user.uid}</p>
<p>Naam: </p>
</div>
</div>
)
}
Can just someone help me out with fetching the logged in user (so not a loop)
In summary, the problem is that I currently get all users back in my console log, but I only need the one that is logged in and on the appropriate dashboard. I would like to post this name (not with a loop but a single request)
To get just the user with a given user_id value, you will have to use a query:
const refUserInformation = database.ref('UserInformation/')
const currentUserQuery = refUserInformation.orderByChild('user_id').equalTo(user.uid);
currentUserQuery.on('value', function(snapshot){
snapshot.forEach((data) => {
console.log(data.val())
});
})
In general, I'd recommend storing user information with the UID as the key. That way:
Each UID can by definition occur only once in the database, since keys are unique under a parent node.
Looking up the user info by their UID becomes simpler, since you won't need a query.
To store the user under their UID use refUserInformation.child(user.uid).set(...) instead of refUserInformation.push(..).

Issues With Persistent React Native Login

I am trying to make a persistent login system with React Native and expo but am running into several issues. I read online that AsyncStorage is the way to do this. I wrote three functions for dealing with login, all seen below.
// use asyncstorage to log in the user
logInUser = async (uid) => await AsyncStorage.setItem('loggedin', uid)
// set loggedin to null in asyncstorage
logOutUser = async() => await AsyncStorage.setItem('loggedin', null)
// returns userid if user is logged in
getUserState = async() => await AsyncStorage.getItem('loggedin')
On my login screen, I use the following onPress event to log in the user.
onPress={() => {
db.logInUser(this.user[1]).then(() => {
//this.removekey(this.user[1]) // delete the user's one-time-login key
this.props.navigation.navigate('Home') // navigate to home
})
}}
Also on the login screen, I use the following componentDidMount function to send the user to the homescreen if they are already logged in.
async componentDidMount() {
db.getUserState().then(loggedin => {
if (loggedin != null) { // log the user in if they have a uid in asyncstorage
this.props.navigation.navigate('Home')
}
})
}
The app will not have a "logout" feature, and users should stay logged in until either buying a new phone or reinstalling the app. Unfortunately this code does not work, and actually automatically logs the user in. I was thinking that it could maybe relate to the user with id=0, but removing this user from the database had no effect. The code of the actual application is here.

How to delete a user with UID from Real Time Database in Firebase?

The database structure looks like this
-LGw89Lx5CA9mOe1fSRQ {
uid: "FzobH6xDhHhtjbfqxlHR5nTobL62"
image: "https://pbs.twimg.com/profile_images/8950378298..."
location: "Lorem ipsum, lorem ipsum"
name: "Lorem ipsum"
provider: "twitter.com"
}
How can I delete everything, including the -LGw89Lx5CA9mOe1fSRQ key programmatically?
I looked at this, but it's outdated and deprecated Firebase: removeUser() but need to remove data stored under that uid
I've also looked at this, but this requires for user to constantly sign in (I'm saving the user ID in localStorage) and it returns null on refresh if I write firebase.auth().currentUser. Data records and user accounts are created through social network providers and I can see the data both on Authentication and Database tab in the Firebase console.
I've tried with these piece of code but it does nothing.
// currentUser has a value of UID from Firebase
// The value is stored in localStorage
databaseChild.child(currentUser).remove()
.then(res => {
// res returns 'undefined'
console.log('Deleted', res);
})
.catch(err => console.error(err));
The bottom line is, I need to delete the user (with a specific UID) from the Authentication tab and from the Database at the same time with one click.
I know that there is a Firebase Admin SDK but I'm creating a Single Page Application and I don't have any back end code. Everything is being done on the front end.
Any kind of help is appreciated.
With suggestions from #jeremyw and #peter-haddad I was able to get exactly what I want. Here is the code that is hosted on Firebase Cloud Functions
const functions = require('firebase-functions'),
admin = require('firebase-admin');
admin.initializeApp();
exports.deleteUser = functions.https.onRequest((request, response) => {
const data = JSON.parse(request.body),
user = data.uid;
// Delete user record from Authentication
admin.auth().deleteUser(user)
.then(() => {
console.log('User Authentication record deleted');
return;
})
.catch(() => console.error('Error while trying to delete the user', err));
// Delete user record from Real Time Database
admin.database().ref().child('people').orderByChild('uid').equalTo(user).once('value', snap => {
let userData = snap.val();
for (let key of Object.keys(userData)) {
admin.database().ref().child('people').child(key).remove();
}
});
response.send(200);
});
Also, if you are facing CORS errors, add the mode: 'no-cors' option to your fetch() function and it will work without any problems.
The link you already found for deleting the user-login-account client-side is your only option if you want to keep the action on the client. Usually you want to keep most of the actions for things like account creation/deletion on the server for security reasons, and Firebase forces the issue. You can only delete your account if you were recently logged in, you can't have client-side start deleting old/random accounts.
The better option is to create your own Cloud Function to handle everything related to deleting a user. You would have to use the Admin SDK that you already found for this... but you could have that Cloud Function perform as many actions as you want - it will have to delete the user from the Auth tab, and delete the matching data in the Database.

Does Firebase send ALL the data under a given path?

I'm a little confused as to how much data is automatically fetched by Firebase and I'm having a hard time modeling data.
As I understand it, an authenticated user's ID is compared to the path; if the key is missing, the path is inaccessible. In addition, once a path is called, all of the data within it is accessed.
For instance, fetching /cart/<$uid>/<item> would also include $uid1, $uid, $uid3 ... $uidN, etc. So if I were to nest all of the data under /<$uid>, like:
/<$uid>/cart
/<$uid>/orders
/<$uid>/transactions
Does this mean that fetching /<$uid>/cart also returns all those other keys? What if I only call <$uid>?
If the structure is instead by cart/ or orders/ first, does this mean all the orders for all the users are fetched?
In other words, when a user logs in, I'd like to retrieve the contents of (using one of those "schemas") the cart:
// Fires onAuthStateChanged()
firebaseListener(function authStateChange(loggedIn, user) {
if (store) {
if (user) {
store.dispatch('getShoppingCart', { uid: user.uid, currentCart: store.getters.cartItemList });
store.dispatch('setUser', user);
}
}
})
getShoppingCart then runs something similar to:
let ref = db.ref('/cart/' + store.state.uid + '/')
ref.on('value', (snapshot) => {
store.cart.concat(snapshot)
})
When a user logs in, you are retrieving the information of that user, so when you use uid, you are retrieving the id of that login user.
When you use this ref('/cart/' + store.state.uid + '/') it will go to cart node first and then the uid of that user and not all userids who are under carts.
You can also use once('value').then(function(snapshot) { which will only read the data once and not trigger again.

firebase add user information while creating user (react.js)

I researched before asking this question but I couldn't find an answer.
I made a form in react js. When I click the button it creates a user with createUserWithEmailAndPassword() method. There is no problem with creating the user. I want to add extra information like; username : "Usernameeeee" to my database. The database will look like this:
users {
userUid1: {name: "Name User 1"}
userUid2: {name: "Name User 2"}
....
}
When I use createUserWithEmailAndPassword(), it creates a user and logs them in. But as you can see the above, I need the current user's id. I know how to get it normally, firebase.auth().currenUser... But while creating a user I can't catch the user's id. It returns null;
export function signUpUser({email, password}) {
return function (dispatch){
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(
() => dispatch({type: USER_SIGNUP_SUCCESS})
)
.then(console.log(firebase.auth().currentUser))
.catch(error => {
dispatch({type: USER_SIGNUP_FAIL, payload: error.message});
});
}
}
When I console the current user, the creating user is complete but not logged in yet. So how can I add information while creating a user ? (not after logged in some other way)
I found the answer after a day. I hope this will be helpful to others. As you understand, the main problem is getting the user id right after creating a user, before user sign in...
So the solution is:
export function signUpUser({email, password, username}) {
const db = firebase.database();
return function (dispatch){
firebase.auth().createUserWithEmailAndPassword(email, password)
// here we get user id if creating is successful.
.then(function(user){
dispatch({type: USER_SIGNUP_SUCCESS}); // I dispatched some message.
db.ref(`users/${user.uid}`).set({name: username}); // I added user
console.log('uid:',user.uid)
})

Categories