I have the following data array in my Firebase app. I want to delete Account3 using AngularFire's $remove method but I can't get it to work
[MY-FIREBASE-URL]
users
simplelogin:1
accounts
0
title: "Account1"
1
title: "Account2"
2
title: "Account3"
3
title: "Account4"
4
title: "Account5"
This is the code I'm using
var fbURL = [MY-FIREBASE-URL];
var ref = new Firebase(fbURL);
var authData = ref.getAuth();
if (authData) {
console.log("User " + authData.uid + " is logged in with " + authData.provider);
var accountPath = fbURL + "/users/" + authData.uid + "/accounts/" + account.title;
//alert(accountPath);
var accountRef = new Firebase(accountPath);
accountRef.remove();
} else {
console.log("User is logged out");
}
In the console.log I see the correct user in the authData but nothing happens. What am I doing wrong?
Try this. I altered the accountRef variable and your $remove() function:
var fbURL = [MY-FIREBASE-URL];
var ref = new Firebase(fbURL);
var authData = ref.getAuth();
if (authData) {
console.log("User " + authData.uid + " is logged in with " + authData.provider);
var accountPath = fbURL + "/users/" + authData.uid + "/accounts/" + account.title;
//alert(accountPath);
var accountRef = $firebaseObject(accountPath);
accountRef.$remove().then(function(accountPath) {
console.log("data has been deleted locally and in Firebase");
}, function(error) {
console.log("Error:", error);
});
} else {
console.log("User is logged out");
}
Thank you #MattDionis for you help. I finally found the answer to my question so here it is for any other newbies like me struggling with a similar issue. In the sample code above the Firebase URL was referencing "account.title" which in fact I needed "account.id", based on the data structure above, to actually remove the entry from my Firebase data.
Related
Im working on a chat app, using firebase and javascript. I encountered a problem, when I switch receivers multiple times, the message that I sent fetches a few times while the messages is sent only once to the database.
var select = document.getElementById("odbiorcy");
select.addEventListener("change", function handleChange(event) {
receiver = select.options[select.selectedIndex].text;
console.log("gonna fetch");
document.getElementById("messages").innerHTML = "";
fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
fetchChat.on("child_added", function (snapshot) {
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
});
Here is how it looks when it fetches, after a switch receivers a few times
As you can see, the first 3 messages that I've sent/received where fine, it was only until I switch the receiver that the message I have sent was duplicated on fetch.
It sounds like you should detach the existing listener when switching receivers in your code.
Something like:
var path, listener;
select.addEventListener("change", function handleChange(event) {
// 👇
if (listener) {
path.off("child_added", listener)
}
receiver = select.options[select.selectedIndex].text;
console.log("gonna fetch");
document.getElementById("messages").innerHTML = "";
fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
// 👇
listener = fetchChat.on("child_added", function (snapshot) {
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
path = fetchChat; // 👈
});
I am still trying to build my website where people can text each other, send photos etc.
The chat thing works really well until I wanna add the functionality checking whether the second user in the chat is typing.
Here is my code without the typing thing, this works really well ;)
firebase.initializeApp(firebaseConfig);
const db = firebase.database();
// temporary user and receiver's names
const username = prompt("Nickname:");
const receiver = prompt("Receiver's name:");
// sending a message
document.getElementById("send-message").addEventListener("submit", postChat);
function postChat(e)
{
e.preventDefault();
const timestamp = Date.now();
const chatTxt = document.getElementById("chat-txt");
const message = chatTxt.value;
chatTxt.value = "";
db.ref("messages/" + username + "/" + receiver + "/" + timestamp).set({
usr: username,
msg: message,
});
db.ref("messages/" + receiver + "/" + username + "/" + timestamp).set({
usr: username,
msg: message,
});
}
// printing the message
const fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
fetchChat.on("child_added", function (snapshot)
{
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
The problem appears when I want to check if the second user is typing. When I am adding the code that's below messages just stop to work. There is a random null in the database as a new user who sent a message to another null. The chat between users also stops to work, users don't see same messages, sometimes can't see any of them and always "undefined" types "undefined" when I refresh the website.
At least it correctly shows when someone is typing, but the rest of the functionalities (which used to work) just don't work anymore.
Here is the code of the typing thing, I also tried to check whether the username and receiver's name aren't null but it didn't reallly help.
// showing whether the receiver is typing
function sendTyping(tmp)
{
if(tmp)
{
db.ref("messages/" + username + "/" + receiver).set({
tpg: "yes"
});
}
else
{
db.ref("messages/" + username + "/" + receiver).set({
tpg: "no"
});
}
}
var searchTimeout;
document.getElementById("chat-txt").onkeydown = function() {
if (searchTimeout != undefined)
clearTimeout(searchTimeout);
searchTimeout = setTimeout(callServerScript, 1500);
sendTyping(true);
}
function callServerScript() {
sendTyping(false);
}
let areTheyTyping = db.ref("messages/" + receiver + "/" + username);
areTheyTyping.on("value", function(snapshot) {
const typing = snapshot.val();
const status = typing.tpg;
if(status == "yes")
document.getElementById("writing").innerHTML = "typing...";
else
document.getElementById("writing").innerHTML = "";
});
I mostly wrote this by myself, I will appreciate any kind of help, just please use a straightforward language so I can easily understand the explanation of the problem, I am kind of new.
The function
const fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
fetchChat.on("child_added", function (snapshot)
{
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
It fetches the chat whenever a child is added to the directory of your messages, so when you store the typing status in "messages/" + username + "/" + receiver + "/" the function .on knows that you've changed/added something, therefore posting a message. It's undefined because the message is in fact empty. You should create a new directory where you store the areTheyTyping status, something like "status/" + username + "/" + receiver + "/" Hope I helped.
My experience showed that firestore has problem with undefined values. You can try adding a default value for undefined or null usernames. Maybe you can add zero (0) as the default value for this matter.
Change the path db.ref("messages/" + receiver + "/" + username) to db.ref("messages/" + username + "/" + receiver) at areTheyTyping. See if it works
function sendTyping(tmp)
{
if(tmp) {
db.ref("messages/" + username + "/" + receiver).set({
tpg: "yes"
});
}
else {
db.ref("messages/" + username + "/" + receiver).set({
tpg: "no"
});
}
}
var searchTimeout;
document.getElementById("chat-txt").onkeydown = function() {
if (searchTimeout !== undefined)
clearTimeout(searchTimeout);
searchTimeout = setTimeout(callServerScript, 1500);
sendTyping(true);
}
function callServerScript() {
sendTyping(false);
}
let areTheyTyping = db.ref("messages/" + username + "/" + receiver);
areTheyTyping.on("value", function(snapshot) {
const typing = snapshot.val();
const status = typing.tpg;
if(status === "yes")
document.getElementById("writing").innerHTML = "typing...";
else
document.getElementById("writing").innerHTML = "";
});
Right now this section of code is passing along undefined to if(customerWaiting >0). It's an issue with async that I can't seem to figure out.
Based off the other threads I looked at, it's very basic and a newbie question, I just can't make it work.
I was seeing if you could find it for me
Edit 1:
the goal of the code is to see if there are customers in the firebase "customerWaiting" database, if there is then display the modal, if there is not then say there are no customers waiting
structure for database is
customerWaiting
-Automatically generated ID
-customer information
Here is the code
var customerWaiting;
var employeeWaiting;
var ref = firebase.database().ref();
$("#connectNextUser").click(function() {
{
ref.child("customerWaiting").on("value", function(snapshot) {
var customerWaiting = snapshot.numChildren();
console.log("There are " + snapshot.numChildren() + " customers waiting");
});
ref.child("employeeWaiting").on("value", function(snapshot) {
var employeeWaiting = snapshot.numChildren();
console.log("There are " + snapshot.numChildren() + " employees waiting");
});
}
if (customerWaiting > 0) {
$("#myModal").modal();
console.log("connect");
} else {
console.log("There are " + customerWaiting + " employees waiting");
console.log("no connect");
}
});
If I understand you correctly you want to do this:
var ref = firebase.database().ref();
$("#connectNextUser").click(function() {
// query how many customers are waiting
ref.child("customerWaiting").on("value", function(snapshot) {
// as soon as you have the result then get the numChildren
var customerWaiting = snapshot.numChildren();
console.log("There are " + snapshot.numChildren() + " customers waiting");
if (customerWaiting > 0) {
// show the modal if customerWaiting > 0
$("#myModal").modal();
console.log("connect");
} else {
console.log("There are " + customerWaiting + " employees waiting");
console.log("no connect");
}
});
});
If you want to use await/async then ref.child("customerWaiting").on("value", resolve) has to support Promises, or you need to convert it to one:
var ref = firebase.database().ref();
$("#connectNextUser").click(async function() {
var snapshot = await new Promise((resolve, reject) => {
ref.child("customerWaiting").on("value", resolve)
// you should also handle the error/reject case here.
})
var customerWaiting = snapshot.numChildren();
console.log("There are " + snapshot.numChildren() + " customers waiting");
if (customerWaiting > 0) {
$("#myModal").modal();
console.log("connect");
} else {
console.log("There are " + customerWaiting + " employees waiting");
console.log("no connect");
}
});
I am trying to find out all the records that matches a user from a Parse class (namely, UserBeaconTracking). I am able to get correct user object and beacon object to begin with. However, when I use the statement
userBeaconTrackingQuery.equalTo("user", user);
Returned Error 102 with an error message "value is expected instead of map type."
What is it that I am doing wrong?
Here is the code snippet:
var userQuery = new Parse.Query(Parse.User);
userQuery.equalTo("username", username);
userQuery.find().then(function(currentUser) { // get the user who sent the request
user = currentUser;
console.log("User" + JSON.stringify(user) + "Beacon Name :: " + JSON.stringify(visitedBeaconName));
}).then(function () { // get the beacons with which user communicated
var beaconRelation = Parse.Object.extend("Beacon");
var beaconQuery = new Parse.Query(beaconRelation);
beaconQuery.equalTo("name", visitedBeaconName);
return beaconQuery.find();
}).then(function (beacons) { // get user beacon transaction details
console.log("number of beacons " + beacons.length + " " + beacons[0]);
visitedBeacon = beacons[0];
console.log("beacon :: " + visitedBeacon);
var userBeaconTracking = Parse.Object.extend("UserBeaconTracking");
var userBeaconTrackingQuery = new Parse.Query(userBeaconTracking);
userBeaconTrackingQuery.equalTo("user", user);
userBeaconTrackingQuery.equalTo("beacon", visitedBeacon);
userBeaconTrackingQuery.find({
success : function (results) {
visitCounter = results[0].get("count");
console.log ("Visit Counter :: " + visitCounter);
// get the list of stores associated with the beacon
var beaconTable = Parse.Object.extend("Beacon");
var brandsAssociatedWithBeacon = new Parse.Query(beaconTable);
brandsAssociatedWithBeacon.get(visitedBeacon.id).then(function(beacon) {
typeOfBeacon = beacon.get("type");
console.log("Beacon Type ::" + typeOfBeacon);
var beaconBrandRelation = beacon.relation("brand");
var query = beaconBrandRelation.query();
//return query.find();
});
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
});
I am currently writing some tests against the code shown below in node.js using mocha. I want to simulate the response from the event emitter 'check_user'. I have sinon.js but I can't get my mind in the right place to work out the best way to simulate the response.
Anyone able to offer some advice on how to go about this?
TgCustomCommand.contact = new Command("contact", "Will send you a users contact card to add to your contact list. Usage is .contact nick", function (input, callback) {
var payload = input;
//Switch our contact to payload.to as this is what our checkuser function looks at
//Check the command over
if (payload.command_args === false) {
payload.response = 'msg ' + payload.to + ' ' + this.description;
return callback(null, payload);
} else {
payload.return = payload.to;
payload.to = payload.command_args; //Set up ready for nick check
//Check the nick exists
emitter.emit('check_user', payload, function (err, result) {
if (err) return callback(err, null);
payload = input; //Reset our payload so we have correct payload.to
//Check how many users we returned
if (result.length === 0) { //Not in our contact list
payload.response = 'msg ' + payload.return + ' I do not have that person in my contact list!';
return callback(null, payload);
} else if (result.length === 1) {
payload.to = result[0].Nick;
payload.response = "send_contact " + payload.return + ' ' + result[0].Phone + ' ' + result[0].Nick + " _";
return callback(null, payload);
}
else {
//loop through our object and create a list of those returned
payload.response = "msg " + payload.return + " I know multiple people with a similar nick: ";
for (var i = 0; i < result.length; i++) {
log.debug(result[i].Nick);
payload.response = payload.response + result[i].Nick + " ";
}
return callback(null, payload);
}
});
}
;
});