Vue 3 Firebase Auth get *any* user data by id? [duplicate] - javascript

This question already has an answer here:
How to get FirebaseUser from a uid?
(1 answer)
Closed 8 months ago.
New to vue/firebase. I was able to lookup how to pull up “current user” data from auth no problem but trying to write a js composable that I can pass in any user id (not necessarily current user) and it will return the user object or at least displayName.
All the docs/vids I can find on the topic reference getting info on *current user *only not another user. From the Google Docs it says I should be able to do this in the "Retrieve user data" section. Closest model to Vue code-wise seems to be “Node.Js” but it isn't working.
Here's what I've got in getUserById
import { getAuth } from 'firebase/auth'
const getUserById = (u) => { // u = user id
const userData = null
getAuth()
.getUser(u)
.then((userRecord) => {
// See the UserRecord reference doc for the contents of userRecord.
console.log(`Successfully fetched user data: ${userRecord.toJSON()}`);
userData = userRecord
})
.catch((error) => {
console.log('Error fetching user data:', error);
});
return { userData }
}
export default getUserById
The error I get is getUser is not a function. I tried adding getUser to the import but same error.

There is no way to look up information about just any user by their UID in the client-side APIs of Firebase as that would be a security risk. There is an API to look up a user by their UID in the Admin SDK, but that can only be used on a trusted environment (such as your development machine, a server you control, or Cloud Functions/Cloud Run), and not in client-side code.
If you need such functionality in your app, you can either wrap the functionality from the Admin SDK in a custom endpoint that you then secure, or have each user write information to a cloud database (such as Realtime Database or Firestore) and read it from there.
Also see:
How to get FirebaseUser from a uid?
Firebase get user by ID
Is there any way to get Firebase Auth User UID?

Related

Limit pages to certain user type Nuxt & Firebase Firestore (Role-Based Authorization)

need some advice here.
My Nuxt & Firebase/Firestore web app will have 3 different type of users:
subcontractor
contractor
worker
First, I want my users, whenever they login, they will log into page related to their user type.
e.g: subcontractor login push to /subcontractor, contractor login push to /contractor etc etc.
I also want the user can only see pages related to their types. (user A only see /A & /Atwo, user B can only see /B & /Btwo, user C, can only see /C & /Ctwo etc etc..)
I want to avoid using cloud functions if can, as from what I understand, you cannot deploy your app in the free plan if your app has cloud functions in it.
Anyway, is below the right way to do it?
Create in firestore, Users document that contains details of user type,
e.g: "userType: subcontractor"
In the middleware, do the logic, based on user type.
(in my case, I need to have 3 diff middleware js file (isSubcontractor.js, isContractor.js, isWorker.js)
add middleware: "the-middleware file", inside my page
If its correct, how to do step 1 & 2?
Is there any articles or real-life application source code that explain briefly what I wanted?
Beginner here. Already gone thru here and there around the internet but can't quite find the answer that I wanted :(
Custom Claims are definitely an option but that would require Cloud functions or a server. Yes, you can store user type in their Firestore document and check it before the page renders or whenever required. However, you must make sure only authorized users can change their role.
The flow would be as simple as:
User logs in
Reading their role from Firestore document
Redirecting to relevant page
import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
import { getFirestore, doc, getDoc } from "firebase/firestore";
const auth = getAuth();
const firestore = getFirestore();
const login = async () => {
const { user } = await signInWithEmailAndPassword(auth, email, password);
// Reading user document
const docRef = doc(firestore, "users", user.uid);
const docSnap = await getDoc(docRef);
const { userType } = docSnap.data()
switch (userType) {
case 'contractor':
// redirect to /contractor
break;
case 'sub-contractor':
// redirect to /sub-contractor
break;
default:
// redirect to default page
break;
}
}
I also want the user can only see pages related to their types.
You can follow them same method in a server side middleware. First read userType and then check if user is authorized to visit the page. If not, redirect to any other page.
Best part of using Custom Claims is that you can read them in security rules of Realtime Database, Firestore and Storage as well. If you store user type in Firestore you cannot read that in security rules of any other Firebase service. Using Firestore also incurs additional charge for reading user's role every time. You need a Cloud function to set the custom claim only and not read the claim every time.

How to add a user’s name when we sign up with fire base auth [duplicate]

I am trying out firebase auth. I want to store a photo-url and a username when the user signs up. My code for signing up -
const email = signupForm['email'].value;
const password = signupForm['password'].value;
auth
.createUserWithEmailAndPassword(email, password)
.then((cred) => {
console.log(cred);
alert('done');
signupForm.reset();
})
.catch((error) => {
console.log(error);
alert(error);
});
Could someone tell me how to add username and photo-url in signup. I know I can make a collection in a firebase db but I read somewhere that username and photo-url can also be saved in firebase auth
Firebase Authentication doesn't have a user property that stores username. You would have to store that on your own, in a database, and make sure the string is unique.
You can store a profile picture URL using updateProfile(). It will not store the image for you - you can only provide a URL. If you need to store the image file itself, tou should probably consider using another product for that, such as Cloud Storage.
Typically, if you have custom information to store per user, you should do that in a database using the unique ID of the user signed in. This gives you full control, rather than depending on what Firebase Auth provides (which is not much). The purpose of Auth is to validate the user's identity, not store per-user information.

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.

Getting id of the current user from Cloud Functions and Firebase

I am using google cloud functions to register push notifications through firebase. In my app, i have a notifications reference that changes for a current user whenever they get a new follower or like, etc. As of right now I am able to send the notification to the phone whenever that whole reference child changes
For example, if any single post is liked, then it will send a notification. What I need to do is observe the current user to only send the notification that single person.
Here is my JavaScript file
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendPushNotification = functions.database.ref('/notification/{id}').onWrite(event => {
const payload = {
notification: {
title: 'New message arrived',
body: 'come check it',
badge: '1',
sound: 'default',
}
};
return admin.database().ref('fcmToken').once('value').then(allToken => {
if (allToken.val()) {
const token = Object.keys(allToken.val());
return admin.messaging().sendToDevice(token, payload).then(response => {
});
}
});
});
I would like to replace this line:
functions.database.ref('/notification/{id}').onWrite(event => {
With this:
functions.database.ref('/notification/{id}').(The current user ID).onWrite(event => {
How do I get the current users id?
You seem very new to JavaScript (calling it JSON is sort-of a give-away for that). Cloud Functions for Firebase is not the best way to learn JavaScript. I recommend first reading the Firebase documentation for Web developers and/or taking the Firebase codelab for Web developer. They cover many basic JavaScript, Web and Firebase interactions. After those you'll be much better equipped to write code for Cloud Functions too.
Now back to your question: there is no concept of a "current user" in Cloud Functions. Your JavaScript code runs on a server, and all users can trigger the code by writing to the database.
You can figure out what user triggered the function, but that too isn't what you want here. The user who triggered the notification is not the one who needs to receive the message. What you want instead is to read the user who is the target of the notification.
One way to do this is to read it from the database path that triggered the function. If you keep the notifications per user in the database like this:
user_notifications
$uid
notification1: ...
notification2: ...
You can trigger the Cloud Function like this:
exports.sendPushNotification = functions.database.ref('/user_notification/{uid}/{id}').onWrite(event => {
And then in the code of that function, get the UID of the user with:
var uid = event.params.uid;
For Swift 3.0 - 4.0
You can do this:
import Firebase
import FirebaseAuth
class YourClass {
let user = Auth.auth().currentUser
let userID = user.uid
// user userID anywhere
}

Firebase Google OAuth - Auth uid is different from the one returned by the callback for emails that have been previously deleted

I have a simple login button that invokes the following code:
var ref = new Firebase(<MY_FIREBASE_URL>);
ref.authWithOAuthPopup('google', function(error, authData) {
if (error) {
console.log('Login Failed!', error);
} else {
console.log('Authenticated successfully. ID:', authData.uid);
}
}, {
scope: 'email, profile'
});
For new users, it creates an entry in the Auth table in Firebase and assigns a UID to it. This UID is supposed to be the same as authData.uid returned in the callback. However, they are different for user emails that have been previously deleted from the Auth table. Basically, the IDs only match once - for user accounts that have never been stored in the Auth table. If you delete it from Auth and re-do the authentication flow, the ID's will be different.
It appears to me that this is a bug in Firebase's implementation of the unique ID generation algorithm. Has anyone else encountered this issue? Any workarounds?
I'm using Firebase SDK 2.4.2.
EDIT: This is not reproducible using SDK 3.
I think I understand what you're describing and if so then I believe it is a bug:
Create user A with email a
Delete user A from the Firebase console
Create user B with email a
authData.uid for B is the same as A
the uid for B in the Firebase console is some other random string
What you can do as a work around for now would be to delete the user via the 2.x SDK instead of from the Firebase console.

Categories