How to iterate a firebase database using javascript? - javascript

I need to iterate the users of my Firebase Database. I have a token for each user, and I want to send a notification to each user of the database.
My database looks like this:
console.log('Sending a notification to all users');
var ref = functions.database.ref('/users');
for (var token in ref){
console.log('Hello from: '+ ref.token);
}

Your ref is just a reference to a specific path in Firebase Realtime Database. You haven't queried it, so you don't have anything back yet. Try this:
console.log('Sending a notification to all users');
var ref = functions.database.ref('/users');
// Query the database
ref.once('value').then((usersSnapshot) => {
// Get back all the user records and iterate through them.
usersSnapshot.forEach((userRecordSnapshot) => {
// I'm guessing your record id is the token?
const token = userRecordSnapshot.key
// To get the other values, for example
const email = userRecordSnapshot.val().email
});
});```

Related

How to get key of parent

I just want to get the stripe customer ID whenever a new payment method is added to my database.
I'm new to realtime databases and I just need some guidance.
var newPaymentMethodRef = functions.database.ref('/stripe_customers/{uid}/newPaymentMethod');
var stripe_customers = functions.database.ref('/stripe_customers/{uid}');
exports.newPaymentMethod = newPaymentMethodRef.onWrite(event => {
console.log("uid = ${uid}");
console.log("newPaymentMethod created");
});
I've tried
event.key
event.parent.key
event.ref("/stripe_customers/")
I'm obviously lost
If the Stripe customer ID is the value that is passed in the {uid} part if the call to the database, you can get it with:
exports.newPaymentMethod = newPaymentMethodRef.onWrite((change, context) => {
console.log(context.params.uid);
Also see the Firebase documentation on Realtime Database triggers.

Retrieving data on firebase having child key uid (javascript)

I am struggling how to retrieve data from firebase having a child key, such as uid.
here is the structure of my firebase.
Currently I am making an admin panel which can read the order placed by each user and render it through flatlist in react native, but it seems that I can't access their order because every time the user places an order it is stored on their unique User.id
I don't know how to make a reference to the User.id child like firebase.database().ref(orders/${AllUserId}/products)
You can use forEach loop to fetch ids and can get values as so
firebase.database().ref('order').on('value', (snapshot) => {
snapshot.forEach((child) => {
uid = child.key; // gives uid1
child.forEach((snap) =>{
var id = snap.key; // first iteration gives uid2
firebase.database().ref('order/'+uid+'/'+id).on('value', (snapchild) => {
snapchild.forEach((snapshotchild) =>{
console.log(snapshotchild.val());
});
});
});
});
});
This could be more insightful.

Firebase Auth: Edit UID

Is it possible to to change a user's UID in Firebase programmatically? There can't seem to be a way to do so manually within Firebase's console.
TL;DR: If you need to specify the UID, you'll need to create a new user with that UID.
You can't directly change the UID, but I was able to hack something together using the firebase admin API (docs)
My use case was that I needed to change a user's email address. I tried update email with "Update a User", but this actually ended up changing the UID under the hood. In my app, the UID is tied to so much stuff, that I'd have to do a huge architecture change, so this wasn't an option.
The general way I did this with the API was:
Pull Down a user using admin.auth().getUserByEmail
Delete the user with admin.auth().deleteUser
Create a new user with admin.auth().createUser, using relevant data from the getUserByEmail call above, replacing the email address with the new email.
"reset password" in the firebase admin console (I think there's a way to do this programmatically too)
User gets an email to reset their password and they have a new account with their old UID.
Unlike admin.auth().updateUser, createUser actually lets you specify a UID.
Building on the answer by RoccoB, the below is a complete set of instructions for changing a user's UID:
Create a new folder, and run npm init with default values.
Run npm install firebase-admin.
Create a NodeJS script file (eg. UpdateUserUID.js), with this code:
let admin = require("firebase-admin");
// config
let email = "XXX";
let serviceAccountData = require("XXX.json");
let adminConfig = {
credential: admin.credential.cert(serviceAccountData),
databaseURL: "https://XXX.firebaseio.com",
};
let newUserOverrides = {
uid: "XXX",
};
Start();
async function Start() {
console.log("Initializing firebase. databaseURL:", adminConfig.databaseURL);
admin.initializeApp(adminConfig);
console.log("Starting update for user with email:", email);
let oldUser = await admin.auth().getUserByEmail(email);
console.log("Old user found:", oldUser);
await admin.auth().deleteUser(oldUser.uid);
console.log("Old user deleted.");
let dataToTransfer_keys = ["disabled", "displayName", "email", "emailVerified", "phoneNumber", "photoURL", "uid"];
let newUserData = {};
for (let key of dataToTransfer_keys) {
newUserData[key] = oldUser[key];
}
Object.assign(newUserData, newUserOverrides);
console.log("New user data ready: ", newUserData);
let newUser = await admin.auth().createUser(newUserData);
console.log("New user created: ", newUser);
}
Replace email and adminConfig.databaseURL with the correct values.
Replace newUserOverrides.uid with the desired new uid. (you can change some other fields too)
Generate/download a private key for your project's Firebase Admin service account: https://firebase.google.com/docs/admin/setup (can skip to the "Initialize the SDK" section)
Update the serviceAccountData variable's import to point to the key json-file from the previous step.
Run node ./UpdateUserUID.js.
If applicable (I didn't seem to need it), use the "reset password" option in the Firebase Admin Console, to have a password-reset email sent to the user, apparently completing the account update. (Perhaps I didn't need this step since I don't use the accounts/authentications for anything besides sign-in on my website...)
The UID of a user is controlled by the identity provider that creates that user. This means that you can't change the UID for any of the built-in providers.
But you can control the UID if you create a custom identity provider. Note that this is quite a bit more involved than changing something in the Firebase console. It requires you to write code that runs in a secure/trusted environment, such as a server you control, or Cloud Functions.
You can't, since is the main tree node of possibles more entries inside it, you can get it, modify and then put it inside the same UID (or create a new one) but you can have things inside, for example take this.
You create your main UID which will hold user data (name, phone, email etc) lets say the structure is this:
-9GJ02kdj2GKS55kg
-Name:
-Phone:
-Email:
so, you can get the main user UID 9GJ02kdj2GKS55kg with mAuth.getCurrentUser().getUid(); and then change it and set a new value inside 9GJ02kdj2GKS55kg, this new value should be the same UID you got but changed, and then inside your main UID you can still have the same structure
-9GJ02kdj2GKS55kg
-6GL02kZj2GKS55kN (this is your changed UID)
-Name:
-Phone:
-Email:
or you can get that changed UID and make a new child, and that will be your parent node with custom UID for the data.
Piggybacking on #Vinrynx's post.
I recently created a migration tool where I am migrating collections from 1 Firebase Project to another and it required that after I insert users to "users" collection I also create an authentication record with the same doc.id
Variables in the functions below:
outCollData : Data that I am inserting for the user (contains the email inside it)
sourceDBApp : output of the admin.initializeApp({/*service-account.json file location for source firebase project */});
destDBApp : output of the admin.initializeApp({/*service-account.json file location for destination firebase project */});
async function updateUsersUID(
outCollData: any,
sourceDBApp: admin.app.App | undefined,
destDBApp: admin.app.App | undefined
) {
if (destDBApp === undefined) return;
const admin = destDBApp;
const email = outCollData.personali.email ? outCollData.personali.email : "";
console.log("Email is ", email);
if (email === "" || email === undefined) return;
console.log("Inside updateUsersUID");
let newUserOverrides = {
uid: outCollData._id,
};
let oldUser: any;
try {
console.log("Starting update for user with email:", email);
oldUser = await admin.auth().getUserByEmail(email!);
//console.log("Old user found:", oldUser);
if (oldUser.uid === outCollData._id) {
console.log(
"User " +
email +
" already exists in the destination DB with UID " +
outCollData._id
);
return;
}
await admin.auth().deleteUser(oldUser.uid);
console.log("Old user deleted.");
} catch (e) {
console.log("User not found in destination DB ", email);
console.log("Copying the user data from source DB");
oldUser = await sourceDBApp?.auth().getUserByEmail(email);
}
let dataToTransfer_keys = [
"disabled",
"displayName",
"email",
"emailVerified",
"phoneNumber",
"photoURL",
"uid",
"providerData",
];
let newUserData: any = {};
for (let key of dataToTransfer_keys) {
newUserData[key] = oldUser[key];
}
Object.assign(newUserData, newUserOverrides);
//console.log("New user data ready: ", newUserData);
let newUser = await admin.auth().createUser(newUserData);
console.log("New user created ");
}

Checking data in deep array with includes (Firebase retrieve data JS)

So I am new to the Firebase database and what I like about it is that I don't have to build a whole backend for just storing some simple data. What I am trying to do is pushing data to an array that I like to recieve from firebase. Then after that I would like to check if the email that was filled in, is included in the data from the firebase database. But because it's firebase and it has multiple arrays, objects etc I don't know how to check that. So the flow is: User fills in data, Applications makes a call to the firebase db and the Application is retrieving the current data from firebase. Then the Application will check if the data that is inputed is already there, and if so, will throw an alert that the data is already in the database. If not, the data will be submitted.
Also, I am wondering if this is the right way to retrieve data from the database:
Main.js
function writeUserData() {
var name = document.getElementById("name").value;
var email = document.getElementById("email").value;
firebase.database().ref('/aanmeldingen/').push({
username: name,
email: email,
});
var dbRef = firebase.database().ref().child('/aanmeldingen/');
dbRef.on('value', snapshot => {
const snap = snapshot.val();
const array = [];
array.push(snap);
console.log(array);
const res = array.includes(email);
console.log(res);
console.log(email);
});
}
Output in console
As you can see this returns multiple data. The include function will check on the submitted emailadress. This returns false even I had inputted "info#webpack.com". How can I check the right data object? It has to check all objects under "0" and return in the console if the submitted emailadress is already there.
I haven't tested it yet but i hope you get the idea. Also this is not the most efficient way to do this.
function ifEmailExist(arr,email){
var _t = 0;
for(var x in arr){
for(var y in arr[x]){
if(arr[x][y].email){
if(arr[x][y] === email){
_t++;
}
}
}
}
return _t;
}
Usage:
if(ifEmailExist(arr,"info#webpack.com") > 0){
//do stuff
}
You should use child_added instead of value. Whenever a new node is added in database, child_added will trigger and then you can take action on the data.
var dbRef = firebase.database().ref().child('aanmeldingen');
dbRef.on('child_added', snapshot => {
var username = snapshot.val().username;
var email = snapshot.val().email;
console.log(username);
console.log(email);
});

Select child_added, firebase

I am creating a query in Firebase, and I have as data the uid, how can I improve the query to get (name, surname) if I have a structure like the following.
I just want the data of the logged in user.
My code is this:
const v_uName = document.getElementById('id_nameU');
var v_userId = firebase.auth().currentUser.uid;
console.log(v_userId);
var v_ref1 = firebase.database().ref().child('/ad_persona/');
v_ref1.on('child_added', function(v_snap1){
v_ref1.child(v_snap1.key).on('child_added', function(v_snap2){
v_ref1.child(v_snap1.key).child(v_userId).on('value', function(v_snap3){
console.log(v_snap3.val());
});
});
});

Categories