Firebase Functions app_remove , get userid - javascript

I am trying to create a new entry (with userid) in my firebase database as soon as a user removes my app. (Qndroid)
'use strict';
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
exports.appremoved = functions.analytics.event('app_remove').onLog(event => {
console.log("App remove detected");
var user = admin.auth().currentUser;
var uid;
const uid2 = event.data.user.userId;
console.log("App remove detected2:" + uid2);
if (user != null) {
uid = user.uid;
console.log("User object not empty" );
admin.database().ref('/user_events/'+uid + "/"+Date.now()).set("app_remove");
}
});
I created two variables to get the user id, but both of them are undefined.
uid2 is undefined, and user is null.
I also tried
const user = event.data.user;
But it is also null
How do I get the userid of the user that removed the app?

Calling admin.auth().currentUser gets you the administrative user that is running the admin SDK. This user does not have a UID. And even if they did, it wouldn't be the user that removed the app.
Calling event.data.user.userId gives you the user ID that your app may have set via the setUserId API. If you didn't set a UserId, the call won't give you any value.

Related

Firebase save function error when updating database

I am trying to update my price, and I keep getting this error upon clicking the Save button. This is the error code I'm getting:
Uncaught ReferenceError: user is not defined
at updatePrice (settings.js:52:43)
at HTMLButtonElement.onclick (VM148 settings.html:284:132)
I have provided my JavaScript code below. This is how I'm calling my function in HTML as well:
<button class="priceSave" type="submit" id="save11" value="save11" onclick="updatePrice()">Save</button>
JavaScript code updated:
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// Initialize variables
const database = firebase.database();
const auth = firebase.auth();
firebase.auth().onAuthStateChanged((user) => {console.log(user);});
function updatePrice() {
// Get data
numberInput = document.getElementById("numberInput").value;
const user = firebase.auth().currentUser;
// Enter database location
firebase
.database()
.ref(user.uid + "/prices/roomA/serviceOne")
.update({
//studioName : studioName,
numberInput: numberInput,
});
}
As a matter of fact, user is not defined in the updatePrice() function. In your code, it's only within the callback function passed to the onAuthStateChanged() observer that user is defined.
You need to use the currentUser property as follows:
function updatePrice() {
//Get data
numberInput = document.getElementById("numberInput").value;
const user = firebase.auth().currentUser;
//Enter database location
firebase
.database()
.ref("/studiopick/studio/users" + user.uid + "/prices/roomA/serviceOne")
.update({
//studioName : studioName,
numberInput: numberInput,
});
}
However, you need to take into account that currentUser could be null. This can happen if the auth object has not finished initializing (more information by reading the entire following documentation section).
So, for example, before calling this function, check that firebase.auth() is not null. If it is the case, you can retry in some few seconds or indicate the user to try later.

How to create a module using mongoose for sharing a changing DB connection

i've been working on an app(Node.js with MongoDB using mongoose), and the server connects to 2 different databases, 1 generic containing username and password pairs for user authentication. Then, when the user signs in, I want to connect to a different database, named after the user's userId. I managed to create a module for sharing the generic UA database, but it's more difficult with the second one, since it doesn't open with the connection, but later on, when the user signs in. I guess i got inspired by the idea of react context kind of sharing.
So far i've got something like this
const mongoose = require("mongoose");
/*
UA = User Authentication
US = User Specific
DB = DataBase
*/
const UA_DB = mongoose.createConnection(/*...*/);
);
const User = UA_DB.model("User", require("../../data-schemas/user"));
let US_DB, Order, Item, Ingredient, Place;
console.log("opened UA database");
function sendUserId(newUserId) {
userId = newUserId;
US_DB = mongoose.createConnection(/*... ${newUserId} ...*/ );
Order = US_DB.model("Order", require("../../data-schemas/order"));
Item = US_DB.model("Item", require("../../data-schemas/item"));
Ingredient = US_DB.model(
"Ingredient",
require("../../data-schemas/ingredient")
);
Place = US_DB.model("Place", require("../../data-schemas/place"));
console.log("opened US database");
}
module.exports = {
UA_DB: {
User,
},
US_DB: {
Order,
Item,
Ingredient,
Place,
},
sendUserId,
};
Now, if I hadn't made it clear, the first, UA_DB works just fine, the user signs in just fine... When it comes to the US_DB i always get undefined as values(Cannot read property 'find' of undefined). I suspect the problem could be, that the exported value doesn't update with the value of the variables. Any ideas, how this could be solved?
Well, i figured it out. Instead of using precise values I use a function to return them, and to connect to the database.UserId is stored in a token, so after verification i check whether i am already connected to the right database (with the userId variable, which stores previous values) and then return curretn values of the models now my code looks something like this
const mongoose = require("mongoose");
/*
UA = User Authentication
US = User Specific
DB = DataBase
*/
const UA_DB = mongoose.createConnection(/* ... */
);
const User = UA_DB.model("User", require("../../data-schemas/user"));
let US_DB,
Order,
Item,
Ingredient,
Place = "some default value";
console.log("opened UA database");
let userId = "";
function getUS_DBModels(newUserId) {
if (newUserId !== userId) {
userId = newUserId;
US_DB = mongoose.createConnection(`...${userId}...`
);
Order = US_DB.model("Order", require("../../data-schemas/order"));
Item = US_DB.model("Item", require("../../data-schemas/item"));
console.log("opened a US_DB connection");
Ingredient = US_DB.model(
"Ingredient",
require("../../data-schemas/ingredient")
);
Place = US_DB.model("Place", require("../../data-schemas/place"));
}
return {
Order, Item, Ingredient, Place
}
}
module.exports = {
UA_DB: {
User,
},
getUS_DBModels,
};
For anyone wondering, in different modules you can access the values like this
const dbHandler = require("./path/to/the/module");
const { Item } = dbHandler.getUS_DBModels("UserId");

How to use cloud function trigger based on two collections documents

I have a collection ReferalCodes in which each document is specified has these values where 'mine' value is false 'msg' value is false and mycode is user referal codes.
appliedcode: ""
mine:false
msg:false
mycode:"ASDF4G"
referals : []
And User has one more collection UserTransaction which have a field 'CountTrans' which is initialized as 0 when this value is 1 i want to trigger a function to check value of mine and appliedcode if the value of mine is true then and applied code have value of length 6 then i want to update the UserTransaction of that user and the appliedcode is referal code of some another user want to change UserTransaction of that user also
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const { user } = require('firebase-functions/lib/providers/auth');
admin.initializeApp();
const db = admin.firestore();
exports.getCount= functions.firestore
.document('UserTransactions/{id}')
.onUpdate((change, context) => {
const newTransdata = change.after.data();
const previousTransData = change.before.data();
const docid = context.params.docid;
if(newTransdata.CountTrans === 1) {
const referalData = await
admin.firestore.collection('ReferalCodes').doc(docid).get()
const mine = referalData.mine;
const appliedCode = referalData.appliedCode;
let codes = [];
var myfrindid;
if(mine === true && appliedCode !== null) {
const friendData = await
admin.firestore.collection('ReferalCodes').doc('codes').get();
var referalcodes = friendData['ReferalCodes'];
referalcodes.forEach((items) =>{
if (items['code'] == appliedCode) {
myfrindid = items['id'];
}
});
await
admin.firestore.collection('ReferalCodes').doc(docid).update({
msg: true
})
}else{
}
}
});
Consulting the official documents is explained how to handle events on your database and trigger some different kind of triggers depending on your needs, for example:
onWrite(), which triggers when data is created, updated, or deleted in Realtime Database.
onCreate(), which triggers when new data is created in Realtime Database
onUpdate(), which triggers when data is updated in Realtime Database
onDelete(), which triggers when data is deleted from Realtime Database
For example, the first argument passed your onUpdate handler function is a Change object, this object has two properties, before and after, both DataSnapshot objects. These DataSnapshot objects describe the contents of the database before and after the change that triggered the function.
exports.foo = functions.database.ref('/location-of-interest')
.onUpdate((change) => {
const before = change.before // DataSnapshot before the change
const after = change.after // DataSnapshot after the change
})

Data not formatting correctly

I'm trying to send the UserID of a created user to my database. I want to then reference data inside of the userID in the database.
In regards to the issue, I'm unaware of how L2GIZ7Sx-e-AALSJp4g and the others below were generated. The UserIDs are then attached to this identifier.
firebase.auth().onAuthStateChanged(User => {
console.log("user id: " + firebase.auth().currentUser.uid);
var UserID = firebase.auth().currentUser.uid;
var ref = firebase.database().ref("Users").push(UserID);
console.log("user logged in");
alert("You have been signed in");
});
I would like the data to be stored as,
+Users
+userid
data about user
Thank you.
When you call push() on a location, Firebase generates a unique key under that location (the values starting with -L in your screenshot).
If you want to instead determine the name of the child node yourself, you should use child(...) instead of push():
firebase.auth().onAuthStateChanged(User => {
console.log("user id: " + firebase.auth().currentUser.uid);
var UserID = firebase.auth().currentUser.uid;
var ref = firebase.database().ref("Users").child(UserID).set(true);
console.log("user logged in");
alert("You have been signed in");
});
The above sets the value of the node to true, since Firebase won't store a node without a value.

Cloud Function for Firebase Type Error - Cannot Read Property

I'm trying to write a Cloud Function that creates a record whenever someone uses our legacy app to create a record (we have changed the Firebase backend architecture and want to slowly migrate users). However, I'm getting the following error in my logs:
TypeError: Cannot read property 'update' of undefined
at exports.makeNewComment.functions.database.ref.onWrite.event (/user_code/index.js:14:92)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:35:20
at process._tickDomainCallback (internal/process/next_tick.js:129:7)
Here is the script in question:
//required modules
var functions = require('firebase-functions');
const admin = require('firebase-admin');
// Listens for new comments added to /comments/ and adds it to /post-comments/
exports.makeNewComment = functions.database.ref('comments/{commentId}').onWrite(event => {
// Grab the current value of what was written to the Realtime Database.
const commentId = event.params.commentId;
const comment = event.data.val();
// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to the Firebase Realtime Database.
//return event.data.ref.parent.child('post-comments').set(comment);
return functions.database.ref('post-comments/' + comment['postID'] + '/' + commentId).update(comment).then(url => {
return functions.database.ref('user-comments/' + comment['postedBy'] + '/' + commentId).update(comment);
});
});
//initialize
admin.initializeApp(functions.config().firebase);
Thanks!
You can't use functions.database.ref() in the middle of a function to get a ref to somewhere in your database. That's only for defining a new Cloud Function.
If you want a ref to somewhere in your database, you can use event.data.ref or event.data.adminRef to get a ref to the location where the event triggered. You could then use the root property of that to rebuild a new ref to somewhere else in the database. Or you can use your admin object to build a new ref.
It might be helpful to look at some sample code to get a sense of how things work.
Based on Doug's answer, you can replace functions.database.ref with event.data.ref.root.
var functions = require('firebase-functions');
const admin = require('firebase-admin');
exports.makeNewComment = functions.database.ref('comments/{commentId}').onWrite(event => {
const commentId = event.params.commentId;
const comment = event.data.val();
return event.data.ref.root.child('post-comments/' + comment['postID'] + '/' + commentId).update(comment).then(url => {
return event.data.ref.root.child('user-comments/' + comment['postedBy'] + '/' + commentId).update(comment);
});
});
admin.initializeApp(functions.config().firebase);

Categories

Resources