Check if users are in conversation with $in operator - javascript

How can i make my code search for two user ids but take in consideration if its more users?
lets say my db only contains a conv with user 10 and 4.
my code:
return Conversations.findOne({"users.userid": { $in: SearchUsers }}).then(function (response) {
return response;
});
Test 1: users with ids: [10,4] -> would return the conversation. aka ( true)
test 2: users with ids [10,4,8] -> This example would NOT return it. Even that both 10 and 4 is in the users, cause there is more members in it, and therefore not a private for them alone. , because it does not have an match, even that 10 and 4 is there, there is a user with id 8, and it dosent exist. ( false )
The idea is to make like facebook has, group chat system, and in this particular matter, to check if an conversation exists or not.
Ideally the $searchUsers could contain anything from 1-50+ userids, and i need it returned if all the users are in a match, if not all is in it, then it wont return any.

tryThe $all operator : it should behave like an $and with $in
Conversations.findOne({"users.userid": { $all: SearchUsers }}).then(function (response) {
return response;
});

Related

How do I toggle between connect and connected

I have a MySQL Database with an array called connectionList . The array for a user contain several objects with a senderID and receiverID fields and would sometimes be empty if the user has no pending connection request.
I have successfully mapped through the array to fetch out the data to the browser. I am however having issues when I have to use the ifelse statement to make a button toggle between connect if the connectionList array is empty or doesn't contain a senderID that matches the id of the logged in user and connected if the array contains an object having a senderID id that matches the id of the logged in user. I need assistance on what to do.
What I have done
{connectionList && connectionList.map(function (conn){
if(conn.senderID === user.id){
return <>Connected</>
} else {
return <>Connect</>
}
})}
You can use optional chaining (?.) in combination with some: The .some(conn => conn.senderID === user.id) checks if the callback is true for at least one element in it (in your case at least one connection is from the current user). The ?. is an optional shortcut which returns undefined if connectionList is undefined or will call the method if it's not undefined.
Together this will return <Connected> if at least one connection sender is the current user, else <Connect>.
{
connectionList?.some(conn => conn.senderID === user.id) ?
<Connected>
: <Connect>
}
On a side note: you don't want to use .map except if you want one result per element in the list. In your case you only want one result for the whole list.
You can achieve it by below code
{
connectionList ?
<>
{connectionList.map(conn => {
<>
{conn.senderID === user.id ?
<>Connected</>
:
<>Connect</>
}
</>
})}
</>
:
<>Connect</>
}

how to get users from firestore database with Like query

this function work fine with equal string but i need to search a substring: if i write "h" and the string is "hello" i need to return that
async getUsers(searchUser) {
return firestore().collection('Users').where(searchUser).where('firstName', '==', searchUser)
.limit(20).get().then(snapshot => {
snapshot.docs.forEach(doc => {
const usersData = { ...doc.data(), id: doc.id };
return usersData
});
})
}
I can give you answer!
In that case, you must use a dedicated third-party search service. These services provide advanced indexing and search capabilities far beyond what any simple database query can offer.
Please use "Algolia" and at that time your code according to your expectations must be like this.
const client = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
const index = client.initIndex('firstName');
index.search(searchUser, {
attributesToRetrieve: ['firstname', 'lastname'/*, .. etc the fields you need*/],
hitsPerPage: 20 /* the page Size */,
}).then(({ hits }) => {
console.log(hits); // the results you want
});
Just try it.
Helpful for you? If it's successful, I would be happy.
If you have a question please contact "Nykolai.B0411#outlook.com". I will help you.
Thanks.
When you register a new user to your app you can store their username/firstname in firestore as an array that includes the possible ways you would search for a user (look at the attached image). You can do that by splitting the name string.
then you can query the users collection by searching in that array using arrayContains like this:
await usersCollection
.where('searchOptions', arrayContains: searchText)
.get()
.then((value) =>
value.docs.map((doc) => User.fromSnapShot(doc)).toList());
If you need more capabilities than that you might need to use a 3rd party service. but this solution should be sufficient for your case.

Add multiple values to the URL dynamically

I am trying to make a request to an endpoint that expects only one user account Id, so I tried to separate the user account Ids (if they are multiple) by &. The this.account is an array with account Id strings. And this is how I am doing it but it still appends the values with a comma:
getAccountStats(callback) {
let acc = this.account.map((val) => {
if (val>1) {
return 'accountID_'+val+'&'
}
return 'accountID__'+val;
})
let url = `/${acc}/userAccount`;
axios.get(url, callback);
}
When I console.log the url, it returns /accountID_1,accountID_2/userAccount but I want it to be /accountID_1&accountID_2/userAccount. Any idea how to achieve this. TIA
I am trying to make a request to an endpoint that expects only one user account Id, so I tried to separate the user account Ids (if they are multiple) by &
The short answer is what you think you want won't ever work. If the endpoint only expects 1 account id, then trying to add more won't do what you want.
but I want it to be /accountID_1&accountID_2/userAccount
This doesn't look like a valid endpoint. So I doubt you really want this.

Running a collection group query to see if a field in my firebase subcollection is true or false

I'm creating a sign in method that is trying to check if my current user has agreed to my terms of agreement after verifying their email address. My function is as follows:
SignIn(email, password) {
return this.afAuth.auth.signInWithEmailAndPassword(email, password)
.then(cred => {
this.ngZone.run(() => {
// Gets current signed in user.
this.afAuth.authState.subscribe(user => {
// Queries Details subcollection.
this.db.collection('users').doc(user.uid).collection('Details')
.get().toPromise().then(
doc => {
if (user.termsOfAgreement == false) {
this.router.navigate(['terms']);
} else {
this.router.navigate(['dashboard']);
}
})
})
});
}).catch((error) => {
window.alert(error.message)
})
}
I know that I'm getting the firebase user object and that it doesn't contain my specific sub collection field names (i.e. user.termsOfAgreement). But how would I access those? I'm trying to check if my termsOfAgreement field is true or false.
My Firestore User Collection state on sign up
User (Collection)
- lastLogin: timestamp
- name: string
- userId: string
Details (subcollection)
- termsOfAgreement: false
First note that this.db.collection('users').doc(user.uid).collection('Details') is not a collection group query, but a read operation on a single collection.
It sounds like you want to check if the Details collection under the user document contains a document with termsOfAgreement equal to true. You can most easily check that with:
firebase.firestore()
.collection('users').doc(user.uid)
.collection('Details').where('termsOfAgreement', '==', true).limit(1)
.get().then((querySnapshot) => {
if (querySnapshot.empty == false) {
this.router.navigate(['terms']);
} else {
this.router.navigate(['dashboard']);
}
})
The above code is using the regular JavaScript SDK, as there is no need to use AngularFire for this operation. But aside from that, it'd work the same in either: you fire a query against the collection and then check if there's any results.
In addition to fixing your code, this also optimizes it in two ways:
The query is sent to the server, so that you're only transferring data that matches the condition.
At most one document is transferred, since you only care whether any result exists.
I'm not sure why you're storing termsOfAgreement in the subcollection though.
If you're checking for the existence of any subdocument where the termsOfAgreement is true, you might want to consider adding a termsOfAgreement field to the user document itself, so that you don't need to perform a query across the subcollection.
You'd set this userDoc.termsOfAgreement to true once the user accepts any terms in the subcollection, and then won't have to query the subcollection anymore (simplifying the reading code and reducing the number of read operations).

How to query orchestrate.io

I was searching for an easy and simple database for a little highscore system for a some games I'm developing in javascript.
I saw Orchestrate.io in github's student developer pack. I found a suitable drivermodule nodejs orchestrate and have integrated them.
The problem comes with querying orchestrate for my data. I have managed saving scores and querying them with db.list('collection'), but this seems to not responding with all data. It appered to me that some values are not returned.
I read about the db.search('collection','query') function. But I don't really understand how I could return all data because I don't want to query in a specific way.
My objects are as simple as follows:
{"name":"Jack","score":1337}
As I understand, one has to send a key, when putting such values to an orchestrate-collection. But I'd like to query the whole collection and get the values in a descendant order in regard to the score.
As for now I end up sorting the result on the client-side.
I hope you guys can give me some hints for a query that can sort for specific values!
You have the option to use a SearchBuilder
db.newSearchBuilder() //Build a search object
.collection('collection') //Set the collection to be searched
.sort(score, 'desc') //Set the order of the results
.query("*") //Empty search
.then(function (res) { //Callback function for results
//Do something with the results
})
Source
By default, .list uses a pagination limit of 10. You can either increase that, e.g.:
db.list('collection', { limit: 100 })
Or use .links, .links.next (from the docs):
db.list('collection', { limit: 10 })
.then(function (page1) {
// Got First Page
if (page1.links && page1.links.next) {
page1.links.next.get().then(function (page2) {
// Got Second Page
})
}
})

Categories

Resources