Hellooo ! I would like to make a chatroom (similar to Instagram) in my app. I'm working with react and Firebase and now I'm wondering how to write a function that makes ChatRoom2, ChatRoom3, etc. when you click on the "Add Chat" button?
I figured the best way to structure the db is to go with this structure :
ChatRooms (collection)
ChatRoom1 (document)
Messages (collection)
...
ChatRoom2 (document)
Messages (collection)
...
But I'm not sure how to write the function.
To create a collection you just need to add a document in that CollectionReference.
// The button to create new chat
<button onClick={createNewChat}>
const createNewChat = async () => {
const newChatDoc = await addDoc(collection(db, "ChatRooms"), {
...newChatFields
});
const firstMsgDoc = await addDoc(collection(db, "ChatRooms", newChatDoc.id, "messages"), {
content: "Welcome to Chat."
});
console.log(`New chat created: ${newChatDoc.id}`)
}
Related
Im using next.js and Stripe webhooks to insert checkout sessions to Supabase that will create a customer's order history. I'm able to get the information about the whole order written to a table called 'orders', but am wondering what the best way to add individual items within each checkout session to another table called 'order_items' is. This way I can map through main orders and then the children items. Appreciate any help provided. Here is what I have for getting orders associated with a customer:
const upsertOrderRecord = async (session: Stripe.Checkout.Session, customerId: string) => {
const { data: customerData, error: noCustomerError } = await supabaseAdmin
.from<Customer>('customers')
.select('id')
.eq('stripe_customer_id', customerId)
.single();
if (noCustomerError) throw noCustomerError;
const { id: uuid } = customerData || {};
const sessionData: Session = {
id: session.id,
amount_total: session.amount_total ?? undefined,
user_id: uuid ?? undefined
};
const { error } = await supabaseAdmin.from<Session>('orders').insert([sessionData], { upsert: true });
if (error) throw error;
console.log(`Product inserted/updated: ${session.id}`);
};
The Checkout Session object contains a line_items field which is a list of each item included in the purchase.
However this field is not included in the object by default, and therefore won't be a part of your webhook payload. Instead you'll need to make an API call in your webhook handle to retrieve the Checkout Session object, passing the expand parameter to include the line_items field:
const session = await stripe.checkout.sessions.retrieve('cs_test_xxx', {
expand: ['line_items']
});
I am working on trying to filter events for only 1 server rather than all servers the bot is in, but I'm trying to figure out how to exactly save each guild the bot is in as an collection so I can just filter events based on a guild ID I desire. Is this even possible? This is a snippet of the code I have to date, it's able to display the server names and ID's the bot is currently in, the events are working properly but triggering for all servers rather than the one I desire, how would I go about filtering for one guild collection?
const Discord = require('discord.js')
const bot = new Discord.Client()
const config = require('./config.json')
bot.on('ready', () => {
console.log(`Logged in as ${bot.user.tag}!`);
//Sets Activity
//client.user.setStatus('invisible')
bot.user.setActivity("Discord Cooks", { type: "WATCHING"})
console.log("Set User Activity!");
//Online Webhook
const webhookClient = new Discord.WebhookClient('','');
const embed = new Discord.MessageEmbed()
.setTitle(`${bot.user.tag} is online`)
.setColor('#FFFF00')
.setTimestamp()
webhookClient.send(embed);
bot.guilds.cache.forEach((guild) => {
console.log(guild.name, guild.id);
});
});
bot.on("channelCreate", (channel) => {
console.log(`channelCreate: ID: ${channel.id} Name: ${channel.name}`);
});
bot.on("channelUpdate", (oldChannel, newChannel) => {
console.log(`channelUpdate -> ${oldChannel.name} to ${newChannel.name}`);
});
bot.on("channelDelete", (channel) => {
console.log(`channelDelete: ID: ${channel.id} Name: ${channel.name}`);
});
bot.login(config.bottoken)
You can only execute code if event happened on exact server in much easier way:
if(guild.id == "GUILD_ID") {
// code
}
Also as #MrMythical said, you can just use if (message.guild.id !== "GUILD_ID") return; if you only need to run your code for 1 guild!
I'm currently working on a socket.io based chat application.
I found a LOT of tutorials on how to manage messages, but I'm struggling with the users list.
I'd like to display a list of connected users, with a few twists:
When a user joins the chat, he has to pick a name
Once he has picked a name, he can talk, and see a list with the names of other users
I'm struggling with this last part: for the messages, its quite easy, I can fetch the existing messages in my database. But how can I retrieve and display the list of connected users ?
I tried with the following pieceo f cade, in my react application:
const [players, setPlayers] = useState([])
const [step, setStep] = useState('lobby')
const socket = socketIOClient(ENDPOINT);
useEffect(() => {
socket.emit('data', {
type: 'joinedRoom',
})
socket.on("FromAPI", data => {
if (data.type === 'newPlayer') {
setPlayers([{
name: data.payload.name,
}])
}
if (data.type === 'joinedRoom') {
socket.emit('data', {
type: 'getPlayers',
players,
})
}
if (data.type === 'getPlayers') {
if (data.players && data.players.length) {
setPlayers([...players, data.players])
}
}
});
But this doesn't work: for any new user, the players state fragment is initialized as an empty array.
I'm fairly new to websockets in general, any help about how to handle data-sharing would be greatly appreciated :)
Are you using nodejs on your backend?,if so than u can either create a users arrry,and push new user into tht array when ever a new user is connected.thn u can access tht anytime,dont forget to delete user whn disconnected
I created a discord bot with the goal to generate reactive embeds with emoji-buttons. My problem is all the embeds created with the bot are modified simultaneously once a 'button' is pressed.
Below a pseudo-code of my bot:
const raidEmbed = new Discord.MessageEmbed() //create the embed
//some code to fill the embed
message.channel.send(raidEmbed).then(embedMessage => {
embedMessage.react('❌')
.then(()=>embedMessage.react('⭕')
//more react to create all the 'buttons'
client.on('messageReactionAdd', (reaction, user) => {
//some code to do stuff when the right 'button' is pressed
//then reset the button with this code:
if (user.id !== client.user.id) {
reaction.users.remove(user.id);
}
const newEmbed = new Discord.MessageEmbed()
//code to create the new embed
embedMessage.edit(newEmbed);
}
})
I don't understand why all my embeds are linked together and how to fix this issue.
Your embeds are not all linked together. The issue here is that you are using a global event to check for reactions. This is the part of your code that is the issue:
client.on('messageReactionAdd', (reaction, user) => {
//some code to do stuff when the right 'button' is pressed
//then reset the button with this code:
if (user.id !== client.user.id) {
reaction.users.remove(user.id);
}
const newEmbed = new Discord.MessageEmbed()
//code to create the new embed
embedMessage.edit(newEmbed);
}
What this part of your code is doing is whenever a reaction is added to any message, all of your embeds are edited. This means that even adding a reaction to a message that is not an embed will cause all of your embeds to be modified. messageReactionAdd is a global event, meaning it applies to all messages, not just your embed messages.
The best solution is to use a reaction collector instead of a reaction event. Reaction collectors are created on specific messages, so only the embed you reacted on will be modified.
Here is an example with your code, it may not necessarily be a working example but it should give you a general idea of how to accomplish this:
const raidEmbed = new Discord.MessageEmbed() //create the embed
//some code to fill the embed
message.channel.send(raidEmbed).then(embedMessage => {
embedMessage.react('❌')
.then(()=>embedMessage.react('⭕')
//more react to create all the 'buttons'
const filter = (reaction, user) => (r.emoji.name == "❌" || r.emoji.name == "⭕") && user.id === message.author.id;
const collector = embedMessage.createReactionCollector(filter, { time: 15000 });
collector.on('collect', reaction => {
//some code to do stuff when the right 'button' is pressed
//then reset the button with this code:
reaction.users.remove(message.author.id);
const newEmbed = new Discord.MessageEmbed()
//code to create the new embed
embedMessage.edit(newEmbed);
}
})
You can also use the filter to narrow down which users' reactions should be collected as well as what specific reactions you want to collect.
I am building a fitness website on Wix. What I have is a database collection of all the training videos. When someone purchases a plan the trainer needs to have their own "Trainer Portal" where they can build the plan for the customer. I need the trainer to be able to filter through the database collection videos and then click "ADD". When they click "ADD" it pushes that video to a data collection then on the same page populate a repeater. The filtering videos I have done with no problem, the problem I am facing is pushing the videos from one database to another database within the webpage. I can only push the information about the video to another data collection but not the actual video.
If anyone knows if this is possible then please point me in the right direction.
Here is my code below.
// For full API documentation, including code examples, visit https://wix.to/94BuAAs
import wixData from "wix-data";
let debounceTimer;
export function iTitle_keyPress(event, $w) {
if (debounceTimer) {
clearTimeout(debounceTimer)
debounceTimer = undefined;
}
debounceTimer = setTimeout(() => {
filterTitle($w('#iTitle').value);
}, 200)
// Add your code for this event here:
}
function filterTitle(title) {
console.log($w('#iTitle').value);
$w('#allVideosDatatSet').setFilter(wixData.filter().contains('title', title))
}
export function addVideos(event) {
let toInsert = {
"video1": $w("#videoPlayer1")
}
wixData.insert("Week1", toInsert)
$w("#week1Dataset").save()
.then( (results) => {
let item = results;
console.log("Your video was saved!!!!");
})
.catch( (error) => {
let logErrorMessage = error;
// console.log(error);
} );
}
3 things
First: I'm assuming you have a button with the id of addVideos hence the export function
Your function export function addVideos(event) {} may not be correct, it should be added via the Properties Panel and should read something like export function addVideos_click(event) {} or add it under the page's onReady function like this:
$w("#addVideos").onClick( (event) => {
//put code here
});
Second: You should scope an item if your button is inside a repeater. Read my answer here to understand more about scoping an item from a repeater.
Third: If the button is inside the repeater then your code should look like below:
export function addVideos(event) {
let $item = $w.at(event.context);
let toInsert = {
"video1": $item("#videoPlayer1").src //Missing the .src to get the video source link & also assuming video player is inside the repeater
};
wixData.insert("Week1", toInsert) //"Week1" should be the database id
.then( (results) => {
console.log("Your video was saved!!!!");
})
.catch( (error) => {
console.log(error);
});
}
Regarding this: "I can only push the information about the video to another data collection but not the actual video"
Videos are stored in the Wix Media Manager, the wix database only stores the link to the video which may begin like wix://video so you cannot "move a video" between databases, just the link which you can get via .src if you want the link of a video player.