I have a chat app that I am building in ionic and firebase. I have a simple join channel function that takes the channel id, and adds the current user id to the list of member in the database. According to everything I am seeing it is working correctly, however whenever I go to the firebase console it is not showing the new item in the database. Here is the code I am using to add the item to the database when a user joins a chat channel...
joinChannel(type, user_id) {
return new Promise((resolve, reject) => {
if(this.availableChannels[type] !== undefined) {
console.log("joining channel: " + type);
console.log('for user: ' + user_id);
let update = {};
update['/chat/members/' + type + '/' + user_id] = {active: true, joinedAt: firebase.database.ServerValue.TIMESTAMP};
this.afDB.database.ref().update(update).then(() => {
console.log("updated /chat/members/" + type + "/" + user_id + " to");
console.log({active: true, joinedAt: firebase.database.ServerValue.TIMESTAMP});
this.activeChannel = '/channels/' + type;
resolve(true);
})
} else {
reject("channel_not_found");
}
});
}
Now, if I open up the developer console in chrome and click to join the channel I get this in the console...
joining channel: news
chat.ts:210 for user: [USERIDHERE]
chat.ts:214 updated /chat/members/news/[USERIDHERE] to
chat.ts:215 Object
active: true
joinedAt: Object
.sv: "timestamp"
__proto__: Object
__proto__: Object
So the console shows that the database ran the update, however if I then log into my firebase console, there is no "news" item in the "chat/members" database. I have tried it with different channels, and always I get the same exact response from firebase, saying it updated the database, but in the firebase console that item remains blank.
Just in case it is needed the this.afDB variable is
public afDB: AngularFireDatabase
in the constructor. I know the database is working because I can update things, send messages in chat channels and they appear in the firebase console, but for whatever reason, when a user joins a channel, I get the successful console log, but the database is not updating with the new information. I am really lost on this one and could really use some help.
it seems to me you want to use a set instead of update
this.afDB.database.ref('/chat/members/' + type + '/' + user_id)
.set({active: true, joinedAt: firebase.database.ServerValue.TIMESTAMP});
Related
I wrote this code for a Cloudflare worker.
When a new customer is created on Stripe, a webhook is triggered and returns the new customer data to [...].worker.dev/updateCustomers
The Cloudflare worker will then do the following:
Get the name from the customer JSON object
create a version without the " " around the string
add the new customer to an array called customers[]
for debugging reasons it will response back to Stripe with the following content: New customer name, all customers in the array and the result if the new customer name is contained in the array
If a user opens a connection to "https://[...]workers.dev/validate?licence=eee" it will return "legit" if the name is in the customer array and "failed" if it is not.
Through Stripe I can see the following response from my worker when a webhook is fired: "Customers received: eee Other Customers: demo,demo2,demo3,eee customers.includes(key): true"
That means that the new customer was successfully added to the array and that my code is able to check if a customer is included in the array.
But when a user tries to validate their name directly, only the array contents that are defined in the beginning like "demo", "demo2" get a positive response.
Can anyone help me fix this? Thanks a lot in advance.
addEventListener("fetch", (event) => {
event.respondWith(
handleRequest(event.request).catch(
(err) => new Response(err.stack, { status: 500 })
)
);
});
customers = ["demo", "demo2","demo3"];
/**
* #param {Request} request
* #returns {Promise<Response>}
*/
async function handleRequest(request) {
const { pathname } = new URL(request.url);
if (pathname.startsWith("/api")) {
return new Response(JSON.stringify({ pathname }), {
headers: { "Content-Type": "application/json" },
});
}
if (pathname.startsWith("/validate")) {
let params = (new URL(request.url)).searchParams;
let key = params.get('licence');
console.log(key);
if(customers.includes(key)){
return new Response("legit");
}
else {
return new Response("failed");
}
}
if (pathname.startsWith("/updateCustomers")) {
let clonedBody = await request.clone().json();
let newCustomerName = JSON.stringify(clonedBody.data.object.name);
let newCustomerNameRaw = newCustomerName.substring(1, newCustomerName.length-1);
customers.push(newCustomerNameRaw);
return new Response("Customers recievedd: " + newCustomerNameRaw + " Other Customers: " + customers.toString() + " customers.includes(key): " + customers.includes(newCustomerNameRaw) );
}
//fallback **strong text**not relevant
if (pathname.startsWith("/status")) {
const httpStatusCode = Number(pathname.split("/")[2]);
return Number.isInteger(httpStatusCode)
? fetch("https://http.cat/" + httpStatusCode)
: new Response("That's not a valid HTTP status code.");
}
return fetch("https://welcome.developers.workers.dev");
}
That is because the customers "demo", "demo2" and "demo3" are stored in the webworker as part of the code, so they are present anytime the call is made. The new customer is stored just temporarily in the array whilst the code runs but once the execution ends the customers array content is reset. You will need to use some kind of backend to store the customers if you want to persist the new ones between runs
I've been trying for a project I'm working on to develop a function for a Food chatbot. What I'm currently working on is to perform a method for a user to make a purchase of an order that is stored in firebase realtime database.
The method is set as the method for an actionMap and the actionMap is linked to an intent for knowing when to call the method and for retrieving the parameters.
My current method uses a simple check for a user's existence and status within the database before identifying the existence of the order they're trying to make a purchase for by its id by going through the user's reference path and doing a .forEach to check every order found and look at its parent folder name to check if it matches the user's order id. My code is as follows:
const MakePurchaseACTION = 'Make Purchase';
function makePurchase(app){
let email = parameter.email;
let orderId = parameter.orderId;
var currDate = currDateGenerator();
var name = email.split(".com");
//Check if User exists first in database
var userRef = database.ref().child('user/' + name);
return userRef.once('value').then(function(snapshot) {
if (snapshot.exists()) {
let statusRetrieved = snapshot.child('Status').val();
//Check if user's status in database is signed in.
if (statusRetrieved == "Signed In") {
var orderRef = database.ref().child('order/' + name);
//Check the order table for the user.
return orderRef.once('value').then(function(orderSnapshot){
let orderVal = orderSnapshot.val();
console.log(orderVal);
//Check through every child for the matching id.
orderSnapshot.forEach(function(childSnapshot) {
let orderIdFound = childSnapshot.key;
//let cost = childSnapshot.child('Cost').val();
console.log(orderIdFound);
if(orderId == orderIdFound) {
let eateryName = childSnapshot.child('Eatery').val();
let eateryLocation = childSnapshot.child('EateryLocation').val();
let deliveryAddress = childSnapshot.child('DeliveryAddress').val();
let orderItem = childSnapshot.child('OrderItem').val();
let quantity = childSnapshot.child('Quantity').val();
let cost = childSnapshot.child('Cost').val();
var purchaseRef = database.ref().child('purchase/' + name + "/" + currDate + "/" + orderId);
purchaseRef.set({
"Eatery" : eateryName,
"EateryLocation" : eateryLocation,
"DeliveryAddress": deliveryAddress,
"OrderItem" : orderItem,
"Quantity": quantity,
"Cost": cost,
"DateCreated": currDate
});
app.add("You have successfully purchased Order " + orderId);
} else {
app.add("There is no order with that id.");
}
});
});
} else {
app.add("You need to be signed in before you can order!");
}
}
else {
app.add("Sorry pal you don't exist in the database.");
}
});
}
actionMap.set(MakePurchaseACTION, makePurchase);
After checking through some firebase logs
Firebase Logs screenshot here
Firebase Realtime Database Order Table Sample
I found that the method actually completes Purchase table sample but my dialogflow returns with the stated error of:
Error: No responses defined for platform: undefined and displays "Not Available" back to the user. My question is how do I go about resolving this error?
I want to use the following function to add to-do things from a list that is linked to a user.
$(document).ready(function(){
$("#toDoButton").click(function(){
var lol = $("#somethingToDo").val();
// $("#myList").append("<li> X " + lol + "</li>").addClass("deleted");
$("<li> X " + lol + "</li>").addClass("deleted").appendTo("#myList");
database.ref('users/' + useNumber).push({
data: lol
});
});
});
When I create a user, I do it with the following function:
function recordUser(uid, name, surname) {
var postData = {
name: name + surname,
data: "data"
};
var updates = {};
updates['/users/' + uid] = postData;
return firebase.database().ref().update(updates);
}
Whenever a user signs in, I want only his to-do list to appear.
with the above functions, I can only create a NEW user with undefined ID.
Also I tried using the "data" field to update there the to-do-list
Can someone tell me how I can link user-id with the corresponding "to-do" list?
What am I doing wrong?
Here's my JSON tree
JSON tree
use the user's uid as a key for his todo list node, so you can fetch it at login
This question already has answers here:
Create an empty child record in Firebase
(2 answers)
Closed 6 years ago.
I'm working on a chrome extension and pushing data from a Google-authenticated user to Firebase.
I'm listening for a message coming from another JS file and when it comes in, I want to take the "user profile" object (request) and tack on a property to it, called "visitedLinks". visitedLinks should be set to an empty object.
I do 3 console.logs throughout the code, and in all three cases, the console.logs show "visitedLinks" set to an empty object, yet when I push to Firebase, "visitedLinks" isn't a property.
//Relevant 3 console statements are the following
//console.log('request.accountData = ', request.accountData)
//console.log('userObject test #1 = ', userObject)
//console.log('userObject = ', userObject)
var rootRef = new Firebase("https://search-feed-35574.firebaseio.com/");
if (localStorage.userIsAuthenticated) {
console.log('user is authenticaled')
chrome.runtime.onMessage.addListener(
//listen for messages
function(request, sender, sendResponse) {
//url is coming in from a content script, use localStorage.uid to make database call
if (request.url) {
console.log('message coming from content script')
var uid = localStorage.uid;
var url = request.url;
var userRef = rootRef.child(uid);
newLinkRef = userRef.push(url);
//otherwise, we're getting a message from popup.js, meaning they clicked it again, or they've signed in for the first time
} else {
console.log('message coming from popup')
//here we're passing in all the data from the person's Google user account
var googleUID = request.accountData.uid
//then we make a new object with the key as their google UID and the value all the account data
request.accountData.visitedLinks = {}
console.log('request.accountData = ', request.accountData)
var userObject = {};
userObject[googleUID] = request.accountData;
console.log('userObject test #1 = ', userObject)
//here were checking to see if the UID is already a key in the database
//basically, if they've ever logged in
rootRef.once('value', function(snapshot) {
if (snapshot.hasChild(googleUID)) {
//user has authenticated before, they just happened to click the popup again
console.log('already authenticated, you just clicked the popup again')
} else {
console.log('users first DB entry');
//if they're not in the database yet, we need to push userObject to the DB
//and push their current url to the publicLinks array
rootRef.set(userObject, function(error) {
console.log('error = ', error);
console.log('userObject after DB insert = ', userObject)
});
}
})
}
//figure out if this user has entries in the DB already
//just push the link information onto the "links" node of the db object
//if not, push a ref (to the right place)
// console.log(sender)
});
} else {
console.log('user isnt authenticated')
}
So it turns out that you can't insert empty objects into the database. Similar question answered here: Create an empty child record in Firebase
I have an object called Group, which stores an array of Users (default Parse user) as a column. I am trying to list all of these users' display names (column called "displayName") in a certain group, but for some reason, when I try to use the .get function on a user in the retrieved array, it only gives me the information for the current user. I checked my permissions and ACL and it says for each user Public Read, and the User class has public read and write permissions. Here is the code I am using:
var groupObject = Parse.Object.extend("Group");
var users = [];
var groupQuery = new Parse.Query(groupObject);
groupQuery.get(groupId,{
success: function(group)
{
users = group.get("Users");
for(var i=0;i<users.length;i++)
{
var user = users[i];
console.log("display name: " + user.get("displayName") + "username: " + user.get("username") + "id: " + user.id);
}
doneCallback(users);
},
error: function(object, error)
{
errorCallback(error);
}
});
I am able to console.log all of their ids, and the query is successful, but the only thing I can use get("column") on is the current user (which is part of the group users array).
I think you should use a Relation instead of an Array to store your users in the Group object. It will be way easier to add, remove, fetch and access your user objects via the relation. You also avoid some headache when the list of your users becomes large. Then you should be able to fetch all the users in any given group like this:
var groupObject = new Parse.Object("Group");
groupObject.set("objectId", yourGroupId);
var query = groupObject.relation("Users").query();
Parse.Cloud.useMasterKey();
query.find().then( function(users) {
_.each(users, function(user) {
console.log(user.get("displayName"));
});
});