remove user id from array of object ids - node.js

i have four object ids in an array . i also have a user id. i would like to remove the user id from array of object ids
allowners= [ 5d6caefdbb6f2921f45caf1d, 5d6caee9bb6f2921f45caf1b,
5d6dfcd6e3b11807944348b8, 5d6caefdbb6f2921f45caf1d]
user._id = 5d6caefdbb6f2921f45caf1d
what i tried
const userid = user._id
const vendors = allowners.filter((item) => userid !== item)
The result i got is
vendors = [ 5d6caefdbb6f2921f45caf1d,
5d6caee9bb6f2921f45caf1b,
5d6dfcd6e3b11807944348b8,
5d6caefdbb6f2921f45caf1d ]
the result i am expecting is
vendors = [ 5d6caee9bb6f2921f45caf1b,5d6dfcd6e3b11807944348b8]

If these ids in allowners array are Mongoose ObjectID you'll need to use .equals method on the ObjectID object to compare:
user._id = "5d6caefdbb6f2921f45caf1d"; //even if this is an ObjectID of mongoose
const userid = user._id;
const vendors = allowners.filter(item => !item.equals(userid));
Another Way: Using toString() on ObjectID (will only work when compared to a string -- userid)
vendors = allowners.filter(item => item.toString() !== userid);
Output:
console.info("Filtered IDs::", vendors);
Filtered IDs:: [ 5d6caee9bb6f2921f45caf1b, 5d6dfcd6e3b11807944348b8 ]

Your result should compute to the expected result if your data type match properly. For example:
// Your array of IDs of type {String}
const allowners = ['5d6caefdbb6f2921f45caf1d', '5d6caee9bb6f2921f45caf1b', '5d6dfcd6e3b11807944348b8', '5d6caefdbb6f2921f45caf1d'];
// Your user object with an id of type {String}
const userObject = {
id: '5d6caefdbb6f2921f45caf1d'
}
// Extract the id from your user object, and store in a userId variable If you wish :-)
const userId = userObject.id;
// Using your code with just changes in the variable name (userid -> userId)
const vendors = allowners.filter((item) => userId !== item);
// The result
console.log(vendors); // [ '5d6caee9bb6f2921f45caf1b', '5d6dfcd6e3b11807944348b8' ]

Related

Firebase function - how to create multiple documents from different collections

I am fairly new to writing functions and cannot figure out how to solve my issue or even search for it properly.
I have three collections:
current_projects
vendors
vendor_projects
when a new project is created I want the function to take all documents in vendors, add certain fields from them to vendor_projects, and include the project_id field that is created in current_projects.
Do I need a for loop to accomplish this or is there other syntax that could be utilized?
My current function is below. This creates on document using the new project_id field but doesnt take any of the fields from vendors. Any input is greatly appreciated.
exports.createProjVen = functions.firestore.document("/Current_projects/{id}")
.onCreate((snap, context)=>{
console.log(snap.data());
const id = snap.data().id;
// const collection = context.params.Current_projects;
// const id = context.params.id;
const projectVendors = admin.firestore().collection("project_vendors");
// const vendors = admin.firestore().collection("vendors");
return projectVendors.doc(id).set({
actual: "",
budget: "",
id: "23121",
project_id: id,
toggle: "true",
type: "Fixtures",
vendor_company: "tes",
vendor_contact: "tes",
vendor_email: "jj#j.com",
vendor_id: "test",
vendor_phone_number: "test"});
});
Adding more details:
When a new project is added it creates a record in current_projects.
I want the function to be able to query all documents in the vendor collection when a new record is created in current_projects.
From there, I want to grab the highlighted fields from the vendor documents, add the id from that was created from current_projects (highlighted in the first screen shot), and create a new document in project_vendors (third screen shot below) for every document in the vendors table.
If you are trying to created a document in project_vendors collection for every vendor in vendors after a project is created then you can map an array of promises and then use Promise.all() as shown below:
exports.createProjVen = functions.firestore.document("/Current_projects/{id}")
.onCreate((snap, context) => {
const docSnap = snap.data();
const id = context.params.id;
const vendorsSnap = await admin.firestore().collection("vendors").get();
const vendorsData = vendorsSnap.docs.map((d) => ({ id: d.id, ...d.data() }))
const promises = [];
const vendorPrsCol = admin.firestore().collection("project_vendors");
vendorsData.forEach((vendor) => {
const data = {
projectId: id,
email: vendor.email,
// other vendor fields
}
promises.push(vendorPrsCol.add(data));
})
await Promise.all(promises);
console.log("Vendor Projects added");
return null;
});

Get data by id from firebase

I use firebase on node.js .
My given structure should look like this:
{
...
batch-1:
id-1(suppose):
name:...
phone:...
id-2:
...
id-3:
...
batch-2:
...
batch-3:
...
...
batch-n:
...
}
How can I get an id-1 object by its identifier in such an architecture?
Does the database have to go around all the batches?
Is there a better solution?
The main task: Create a batch with many objects that will have SHORT and a UNIQUE identifier and optimally receive data by this identifier
To search for a particular ID that is a child of a list of unknown IDs, you need to use orderByChild(). In your use case, you are looking for a particular ID in a list of batch IDs. If you used orderByChild() on this list, you would get back results for each and every batch ID, even if it didn't have the ID you wanted. This is because even null (non-existant) values are included (and sorted at the start) in the results. To get the data of the desired ID, you would get the data for the last result of the query, which if it existed, would be sorted to the end of the list. Note that if the desired ID doesn't exist, the last result (if there are any results) would have a null value. To return only the last result of the query, you would use limitToLast(1).
Putting this all together, gives the following code:
let idToFind = "unique-id-1";
let batchesRef = firebase.database().ref(); // parent key of "batch-1", "batch-2", etc.
// assumed to be the database root here
batchesRef.orderByChild(idToFind).limitToLast(1).once('value')
.then((querySnapshot) => {
if (!querySnapshot.numChildren()) { // handle rare no-results case
throw new Error('expected at least one result');
}
let dataSnapshot;
querySnapshot.forEach((snap) => dataSnapshot = snap); // get the snapshot we want out of the query's results list
if (!dataSnapshot.exists()) { // value may be null, meaning idToFind doesn't exist
throw new Error(`Entry ${idToFind} not found.`);
}
// do what you want with dataSnapshot
console.log(`Entry ${idToFind}'s data is:`, dataSnapshot.val());
})
.catch((error) => {
console.log("Unexpected error:", error);
})
For small data sets, the above code will work just fine. But if the list of batches starts growing quite large, you may wish to build an index that maps a particular ID to the batch ID that contains it.
Here is my method which allows you to search by id or to search by key value such as email uniqueemail
// gets primary key
const getSnapshotValKey = snapshot => (Object.keys(snapshot).length > 0 ? Object.keys(snapshot)[0] : null)
const getUser = async ({ id, key, value }) => {
let user = null
const ref = id ? '/users/' + id : 'users'
const userRef = admin.database().ref(ref)
const valueRef = id ? userRef : await userRef.orderByChild(key).equalTo(value)
const snapshot = await valueRef.once('value')
const val = snapshot.val()
if (val) {
const key = id || getSnapshotValKey(val)
user = {
id: key,
...(id ? val : val[key]),
}
}
return user
}

How to select a UUID from a prepared statement in Postgres?

I'm trying to select a user based on a UUID:
const client = await this.pg.connect()
const { rowsAct } = await client.query(`SELECT * FROM users WHERE uid=$1`, [
userUUID
])
I also tried without the variable:
const client = await this.pg.connect()
const { rowsAct } = await client.query(`SELECT * FROM users WHERE uid=$1`, [
'4fcf0ca3-4e26-40a9-bbe5-78ff8fdb6e0f'
])
I tried using ::uuid casting but maybe I did it wrong. The returned rowsAct is always undefined.
I verified the userUUID variable was populated and was a valid uuid:
console.log(typeof userUUID) // string
What am I doing wrong? How can I properly select a row form it's UUID?
Thanks!
You'll need to wrap your argument in parentheses before applying the ::uuid type cast so that the prepared statement can properly interpolate argument.
SELECT * FROM users WHERE uid = ($1)::uuid
You can also cast the column itself to text but it's less performant since the query will have to cast each row.
SELECT * FROM users WHERE uid::text = $1

Cloud Functions & Firestore: Iterate over document.data

The database structure looks like this:
User {id}
Settings (Collection)
device_uids(document)
{device_uid_1}: Boolean
(...)
{device_uid_n}: Boolean
I want to get the document and access all of the device_uids within that document.
I tried like this, however the console logs, that forEach is not definded:
const settings_ref = admin.firestore().collection('User').doc(uid).collection('Settings').doc('device_uids');
settings_ref.get()
.then(snap =>{
let uids = snap.data();
uids.array.forEach(element => {
let device = element.key;
if(device != device_uid){
//GO ON
}
});
})
How can I access the values individually?
You don't have a field called array in your document, so uids.array will always be undefined. If you just want to iterate all the properties of the document, it's just like iterating all the properties of a plain old JavaScript object:
const data = snap.data();
for (const key in data) {
const value = data[key];
// now key and value are the property name and value
}

Confirm collection exists using mongoose

New to MongoDB so I hope I get the terminology correct...
I have a database that includes a user collection. In node I would like to check that value of a field, however, first I need to ensure the field exists.
For example here is my user schema:
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
local: {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
}
}
Some users have both a local and facebook documents/fields? whereas others may have either.
I wish to confirm the is the current user document has an email value in both fields if both fields exist in the document. i.e.
User.local.email & User.facebook.email
If I try to access the email field directly and the field does not exist for that document I get:
TypeError: Cannot read property 'email' of undefined
Try this -
var localExists = User.local != null;
var facebookExists = User.facebook != null;
if(localExists && facebookExists){
// both exist so check if both have email
var bothHaveEmail = User.local.email != null && User.facebook.email != null;
}
else if(localExists){
// only local exists
}
else if (facebookExists){
// only facebook exists
}
else{
// nothing exists
}
You could try
const localEmail = user.local && user.local.email;
const fbEmail = user.facebook && user.facebook.email;
If either is set to undefined that means that that email field doesn't exist

Resources