"array-contains" firebase v9 query giving me an error - reactjs

I am using Sonny Sangha's Whatsapp Clone video (he is using firebase v8 whereas I am using firebase v9)
The code below checks if the input you type in is already present in the Firestore Database, and if this is true, then we alert the user with a message that the user you are trying to chat with already exists. Otherwise, it will create a document in Firestore with the user email and the input you typed (the person you want to chat with).
const chatAlreadyExists = (recipientEmail) => {
// I used "!!" to convert this into boolean
!!chatsSnapshot?.docs.find(
(chat) => chat.data().users.find((user) => user ===
recipientEmail)?.length > 0
);
};
const input = prompt(
"Please enter an email address for the user you wish to chat
with"
);
if (
EmailValidator.validate(input) &&
!chatAlreadyExists(input) &&
input !== user.email
) {
const payload = {
users: [user.email, input],
};
addDoc(collectionRef, payload);
The chatsSnapshot is a real-time listener to the Firestore database
const [user] = useAuthState(auth);
const collectionRef = collection(db, "chats");
const userChatRef = query(
collectionRef,
where("users", "array-contains", user.email)
);
const [chatsSnapshot] = useCollection(userChatRef);

Related

React Firestore query doesn't return found document on first run

I'm building a web app, where users can make appointments with doctors and I want to prevent a user to make an appointment at the same time and date with the same doctor that a different user has already requested. I'm using a firestore database to store the appointments as documents.
This is my function, which handles the check and pushes to my firebase database:
const addAppointment = async (date: Date | null, speciality: string | undefined) => {
const appointmentsRef = collection(db, "appointments");
const q = query(appointmentsRef, where("speciality", "==", speciality), where("date", "==", date))
const docs = await getDocs(q);
docs.forEach((doc: any) => {
console.log(doc.data())
})
console.log(docs.docs.length)
if (docs.docs.length === 0) {
try{
await addDoc(collection(db, "appointments"), {
email: auth.currentUser?.email,
date,
speciality
});}
catch (err) {
console.error(err);
}
return false
}
return true
};
On page refresh, if I try to make an appointment that has already been requested, the docs length is 0 and I can make the same appointment. However, If I try again (without refreshing), the doc length is 1 and nothing is pushed to the db.
I am now parsing the date field as string and I am essentially comparing strings and not dates.

Filter function for Array of Objects

I'm following this tutorial and made a few changes to typescript for learning purposes but got stuck when creating a filter function from react context script.
I have a working function called getCampaigns where it maps all the object from the blockchain like below:
const getCampaigns = useCallback(async () => {
const signer = accountProvider?.getSigner();
const contractWithSigner = contract?.connect(signer);
const campaigns = await contractWithSigner?.getCampaigns();
const parsedCampaigns = campaigns.map((campaign, i) => ({
owner: campaign.owner,
title: campaign.title,
description: campaign.description,
target: ethers.utils.formatEther(campaign.target.toString()),
deadline: campaign.deadline.toNumber(),
amountCollected: ethers.utils.formatEther(
campaign.amountCollected.toString()
),
image: campaign.image,
pId: i,
}));
return parsedCampaigns;
}, [contract, accountProvider]);
This is working as it should and manage to see the content like below:
[{…}]
0:
amountCollected:"0.0"
deadline:1673049600000
description: "I want to build a Robot"
image:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAA
owner:"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
pId:0
target:"3.0"
title:"Build a Robot"
As my new function, I wanted to filter from the getCampaigns function only to display all of the owner's post and display it on a Profile page like below:
const getUserCampaigns = async () => {
const allCampaigns = await getCampaigns();
const filteredCampaigns = allCampaigns.filter(
campaign => campaign.owner === account
);
return filteredCampaigns;
};
So when I console.log filteredCampaigns, it doesnt show any result. Is there anything that I missed here? The typeof account is string and it is working if I put it like this
const filteredCampaigns = allCampaigns.filter(
campaign => campaign.owner === "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
);
Update:
So far I have been playing around with the syntax and console.log the following:
const filteredCampaigns = allCampaigns.filter(campaign => {
console.log(campaign.owner);
return campaign.owner === account;
});
it's managed to fetch the same data and the typeof campaign.owner is in fact a string (same as typeof account). But when I run it like this
const filteredCampaigns = allCampaigns.filter(campaign => {
console.log(campaign.owner === account.toString());
return campaign.owner === account;
});
It's still come out as false
It is working if I hard coded like this
console.log(campaign.owner === "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266")
filteredCampaign is empty, because the content of account doesn't match any content of campaign.owner.
Check the content of account.
allCampaign.filter(elementOfArray => condition)
return element only if condition is true.
The logic of your getUserCampaign, looks right for what you want to do.
Not sure if this is the case, but may have sense, to have a field/global var/state where you keep all your campaigns.
In this way when you want to filter, you can do something like
const filteredCampaign = (account: string) => {
return allCampaigns.filter(campaign => campaign.owner === account);
}
filteredCampaign is not anymore async call, because doesn't have to await and receive the
account

Downloading attachments from specific person's mail using appscript

I have tried to download the attachments by stating the required person's mail but downloading the attachments irrespective of the person's mail. Here is what I have tried.
function saveGmailtoDrive(){
var gmailThread = GmailApp.search('from:xyz#gmail.com subject:"AT TRACKER"');
const folderId ="1ifmrUCLLyvvnOlZi0gde6MWgMoowCZOL"
const searchQuery = "has:attachment"
const threads=GmailApp.search(searchQuery,0,10)
threads.forEach((thread) => {
const messages = thread.getMessages()
messages.forEach((message) => {
const attachments = message.getAttachments({
includeInlineImages:false,
includeAttachments:true
})
attachments.forEach((attachment) => {
Drive.Files.insert({
title:attachment.getName(),
mimeType:attachment.getContentType(),
parents:[{id:folderId}]
},
attachment.copyBlob()
)
})
})
})
}

Firebase v9 on react JS

I just want to check if i dont create an other chats on my firebase.
I query all my chat with this email and then, i check if the array contain the email i wanna tchat with but it doesn't work.
I'm using Firebase V9.
Anyone has an idea ?
function Sidebar() {
const [user] = useAuthState(auth);
const chatRef = collection(db, 'chats');
const qchatExist = query(chatRef, where('users', 'array-contains', user.email) );
const chatsSnapshot = getDocs(qchatExist);
const createChat = () => {
const input = prompt('Please enter a email adresse');
if(!input) return;
if (EmailValidator.validate(input) && !chatAlreadyExists(input) && input !== user.email ) {
console.log("valide");
addDoc(collection(db, 'chats'),
{
users: [user.email, input],
});
}
else {
console.log('invalide');
}
}
const chatAlreadyExists = (data) =>
!!chatsSnapshot?.docs.find(
chat =>
chat.data().users.find( (user) => user === data)?.length > 0
);
code
you probably wanna use Collection Group Queries.
so you can query across all the chats collection at once.
https://firebase.google.com/docs/firestore/query-data/queries#:~:text=We%20can%20use,across%20all%20cities%3A
const users = query(collectionGroup(db, 'users'), where('email', '==', 'example#hoge.com'));
and make sure you create indexes for the query.
Before using a collection group query, you must create an index that supports your collection group query. You can create an index through an error message, the console, or the Firebase CLI.

How can i filter all users badges | DiscordJS V12

I'm trying to do a command to list every users with a certain type of flags, like "HYPESQUAD_BALANCE"
const users = message.mentions.members.first() || message.guild.members.cache.get(args[0]) || message.member;
const flags = await users.user.fetchFlags()
const userFlags = flags.toArray()
const status = userFlags.includes('HYPESQUAD_BALANCE')
console.log(status)
That part of command working fine, but that's not what i want, i want to get every users
So i have tried that
const members = client.users.cache.array()
const array = [];
for (const user of members) array.push(user.flags ? user.flags : await user.fetchFlags());
console.log(array)
No error, but returning anything, if someone can help me
The following code works for me:
const users = client.users.cache.array();
const validUsers = []:
for(let user of users){
const flags = user.flags || await user.fetchFlags();
const hasFlag = flags.toArray().includes("HYPESQUAD_BALANCE");
if(hasFlag) validUsers.push(user);
}
console.log(validUsers); // all the users who have the badge

Resources