How to access data ID in fIrebase - javascript

I am working with Firebase Firestore using Nuxt js and I want to retrieve data from my database. I am using firebase with NuxtFirebase, the official plugin for firebase.
I need to access the ID property from my firebase database
Here is my store
const actions = {
// The Post list API
async postList({ commit }) {
try {
const req = await this.$fire.firestore.collection('Post').get()
const posts = req.docs.map((doc) => doc.data());
console.log(posts)
commit("SET_POST", posts)
} catch (e) {
console.log(e)
}
}
};
export default {
state,
getters,
mutations,
actions,
}
Looking at my console I get the following data
[
{
"title": "Bitcoin is the Detector of Imbeciles",
"created_at": {
"seconds": 1672921367,
"nanoseconds": 80000000
},
"featured_image": "https://firebasestorage.googleapis.com/v0/b/newsly-df76d.appspot.com/o/photo-1565402170291-8491f14678db.jpg?alt=media&token=535d7444-15ad-4f28-af8b-4e3918794c86",
"content": "Last year, 2022 was not of much respite for cryptocurrencies. While bitcoin has lost more than 60% of its value, the entire sector is in crisis, punctuated by various bankruptcies such as those of Terra and FTX.",
"tag": "Business"
},
{
"featured_image": "https://firebasestorage.googleapis.com/v0/b/newsly-df76d.appspot.com/o/photo-1519311965067-36d3e5f33d39.jpg?alt=media&token=4d49b9db-ec6b-4443-81a1-c52bc71bbd06",
"title": "How senior product managers think differently",
"created_at": {
"seconds": 1672921319,
"nanoseconds": 639000000
},
"content": "I often got asked how a product manager could get promoted to a more senior level. The truth is, getting a promotion is often a complicated game. Yes, your skills and achievements play a role, but so do other factors such as how much your manager cares about developing talents, how good and tenured your peers are, how political the company is, etc.",
"tag": "Business"
},
{
"content": "ChatGPT is blowing up. Twitter is inundated with screenshots of the app, coding sites like Stack Overflow are already banning answers produced with it, and over 1 million people have played with it. It’s a sensation. As a professional AI researcher, I wouldn’t have called that. ChatGPT is trained specifically to act as a chat bot, but fundamentally it’s using the same GPT-3 technology that’s been available for over two years now.",
"created_at": {
"seconds": 1672921101,
"nanoseconds": 807000000
},
"title": "ChatGPT Is Having a Thomas Edison Moment",
"tag": "Technology",
"featured_image": "https://firebasestorage.googleapis.com/v0/b/newsly-df76d.appspot.com/o/istockphoto-178586669-170667a.jpg?alt=media&token=f8c15944-080b-40f7-a926-589a8ff07bb4"
}
]
I need to access the ID

The req is a QuerySnapshot and every doc in the map is a QueryDocumentSnapshot that has id property. Try:
const posts = req.docs.map((doc) => ({ id: doc.id, ...doc.data() }));
console.log(posts)

Related

MongoDB: How do I find coordinates nearby?

In this function, I want to check if there are any posts in the database made nearby to a set of input lat/long coords so that I can display them based on where the user currently is, and I also want to write a function to check if they are in a "too close" range (less than 2m or so).
I'm not sure how to do it properly and every answer I have found online after extensive research has given me nothing. I am using NodeJS 18 LTS with the latest version of mongodb.
This is the code I tried to get the posts
const getPostsInRange = (lng, lat) => {
// get all posts in range
const postCollection = db.collection('posts')
return postCollection.find({
"location": {
"$near": [parseFloat(lng), parseFloat(lat)],
"$maxDistance": 100000
}})
}
and here is the code that calls it, from index.js
app.get('/getposts/:lat/:long', requiresAuth(), (req, res) => {
const { lat, long } = req.params
getPostsInRange(long, lat)
.then((posts) => {
res.send(posts)
})
.catch((err) => {
console.log(err)
res.status(500).end()
})
what my data looks like in mongodb:
{
"textBody": "new message 3",
"image": "xxxx",
"location": {
"type": "Point",
"coordinates": [xxxx, xxxx]
},
"timestamp": 1674503437
}
I get errors such as
TypeError: getPostsInRange(...).then is not a function, and similar but slightly different ones that Google seems to have never have heard of.
i would love some help building this project, full code snippets would be greatly appreciate due to my lack of experience working with mongodb.

My Query Quagmire: My node.js program works just fine, except when I try to execute queries, or filtered HTTP requests. Why?

I have been working on the backend of my app. At this point, it can access all data in a data base, and output it. I'm trying to implement some queries, so that the user can filter out the content that is returned. My DAL/DAO, looks like this
let mflix //Creates a variable used to store a ref to our DB
class MflixDAO {
static async injectDB(conn){
if(mflix){
return
}
try{
mflix = await conn.db(process.env.JD_NS).collection("movies")
}catch(e){
console.error('Unable to establish a collection handle in mflixDAO: ' + e)
}
}
// Creates a query to fetch data from the collection/table in the DB
static async getMovies({
mflix.controller
filters = null,
page = 0,
moviesPerPage = 20,
} = {}) {
let query
if (filters){
// Code
if("year" in filters){
query = {"year": {$eq: filters["year"]}}
}
// Code
}
// Cursor represents the returned data
let cursor
try{
cursor = await mflix.find(query)
}catch(e){
console.error('Unable to issue find command ' + e)
return {moviesList: [], totalNumMovies: 0}
}
const displayCursor = cursor.limit(moviesPerPage).skip(moviesPerPage * page)
try{
const moviesList = await displayCursor.toArray() // Puts data in an array
const totalNumMovies = await mflix.countDocuments(query) // Gets total number of documents
return { moviesList, totalNumMovies}
} catch(e){
console.error('Unable to convert cursor to array or problem counting documents ' + e)
return{moviesList: [], totalNumMovies: 0}
}
}
}
export default MflixDAO
Just so you know, I am using a sample database from MongoDB Atlas. I am using Postman to test HTTP requests. All the data follows JSON format
Anyway, when I execute a basic GET request. The program runs without any problems. All the data outputs as expected. However, if I execute something along the lines of
GET http://localhost:5000/api/v1/mflix?year=1903
Then moviesList returns an empty array [], but no error message.
After debugging, I suspect the problem lies either at cursor = await mflix.find(query) or displayCursor = cursor.limit(moviesPerPage).skip(moviesPerPage * page), but the callstacks for those methods is so complex for me, I don't know what to even look for.
Any suggestions?
Edit: Here is an example of the document I am trying to access:
{
"_id": "573a1390f29313caabcd42e8",
"plot": "A group of bandits stage a brazen train hold-up, only to find a determined posse hot on their heels.",
"genres": [
"Short",
"Western"
],
"runtime": 11,
"cast": [
"A.C. Abadie",
"Gilbert M. 'Broncho Billy' Anderson",
"George Barnes",
"Justus D. Barnes"
],
"poster": "https://m.media-amazon.com/images/M/MV5BMTU3NjE5NzYtYTYyNS00MDVmLWIwYjgtMmYwYWIxZDYyNzU2XkEyXkFqcGdeQXVyNzQzNzQxNzI#._V1_SY1000_SX677_AL_.jpg",
"title": "The Great Train Robbery",
"fullplot": "Among the earliest existing films in American cinema - notable as the first film that presented a narrative story to tell - it depicts a group of cowboy outlaws who hold up a train and rob the passengers. They are then pursued by a Sheriff's posse. Several scenes have color included - all hand tinted.",
"languages": [
"English"
],
"released": "1903-12-01T00:00:00.000Z",
"directors": [
"Edwin S. Porter"
],
"rated": "TV-G",
"awards": {
"wins": 1,
"nominations": 0,
"text": "1 win."
},
"lastupdated": "2015-08-13 00:27:59.177000000",
"year": 1903,
"imdb": {
"rating": 7.4,
"votes": 9847,
"id": 439
},
"countries": [
"USA"
],
"type": "movie",
"tomatoes": {
"viewer": {
"rating": 3.7,
"numReviews": 2559,
"meter": 75
},
"fresh": 6,
"critic": {
"rating": 7.6,
"numReviews": 6,
"meter": 100
},
"rotten": 0,
"lastUpdated": "2015-08-08T19:16:10.000Z"
},
"num_mflix_comments": 0
}
EDIT: It seems to be a datatype problem. When I request a data with a string/varchar type, the program returns values that contain that value. Example:
Input:
GET localhost:5000/api/v1/mflix?rated=TV-G
Output:
{
"_id": "XXXXXXXXXX"
// Data
"rated" = "TV-G"
// Data
}
EDIT: The problem has nothing to do with anything I've posted up to this point it seems. The problem is in this piece of code:
let filters = {}
if(req.query.year){
filters.year = req.query.year // This line needs to be changed
}
const {moviesList, totalNumMovies} = await MflixDAO.getMovies({
filters,
page,
moviesPerPage,
})
I will explain in the answer below
Ok so the problem, as it turns out, is that when I make an HTTP request, the requested value is passed as a string. So in
GET http://localhost:5000/api/v1/mflix?year=1903
the value of year is registered by the program as a string. In other words, the DAO ends up looking for "1903" instead of 1903. Naturally, year = "1903" does not exist. To fix this, the line filters.year = req.query.year must be changed to filters.year = parseInt(req.query.year).

Can't query by ID as second parameter with AWS DataStore

I am total noob to AWS, DataStore, and DynamoDB. I can't figure out why this isn't working.
If I attempt query an object related to my users ID from Cognito this seems to work. If I console log I get an array with one User.
let profile = await DataStore.query(User, (u) =>
u.id('eq', user.attributes.sub)
);
// Returns [Model]
console.log('[LOADING USER DATA]', profile);
If I attempt query an object related to my users ID like this. (as recommended by the docs). I get undefined.
let profile = await DataStore.query(User, user.attributes.sub);
// Returns undefined
console.log('[LOADING USER DATA]', profile);
Dynamo Data looks fine to me but am I using the wrong primary key ID field or something?
{
"id": "929e6e62-e3a0-4b84-b050-72c53eebda93",
"_lastChangedAt": 1644433699,
"status": "Active",
"createdAt": "2022-02-09T19:08:18.548Z",
"name": "Test",
"orgs": [
"b6508155-f5cf-49b7-88d6-0e605677c4e4"
],
"_version": 1,
"role": "User",
"updatedAt": "2022-02-09T19:08:18.548Z",
"orgID": "b6508155-f5cf-49b7-88d6-0e605677c4e4",
"title": ""
}
What am I doing wrong?

Optimalization of firebase query. Getting data by ids

I'm new in Firebase. I would like to create an app (using Angular and AngularFire library), which shows current price of some wares. I have list all available wares in Firebase Realtime Database in the following format:
"warehouse": {
"wares": {
"id1": {
"id": "id1",
"name": "name1",
"price": "0.99"
},
"id2": {
"id": "id2",
"name": "name2",
"price": "15.00"
},
... //much more stuff
}
}
I'm using ngrx with my app, so I think that I can load all wares to store as an object not list because normalizing state tree. I wanted load wares to store in this way:
this.db.object('warehouse/wares').valueChanges();
The problem is wares' price will be refresh every 5 minutes. The number og wares is huge (about 3000 items) so one response will be weight about 700kB. I know that I will exceed limit downloaded data in a short time, in this way.
I want limit the loading data to interesing for user, so every user will can choose wares. I will store this choices in following way:
"users": {
"user1": {
"id": "user1",
"wares": {
"id1": {
"order": 1
},
"id27": {
"order": 2
},
"id533": {
"order": 3
}
},
"waresIds": ["id1", "id27", "id533"]
}
}
And my question is:
Is there a way to getting wares based on waresIds' current user? I mean, does it exist way to get only wares, whose ids are in argument array? F.e.
"wares": {
"id1": {
"id": "id1",
"name": "name1",
"price": "0.99"
},
"id27": {
"id": "id27",
"name": "name27",
"price": "0.19"
},
"id533": {
"id": "id533",
"name": "name533",
"price": "1.19"
}
}
for query like:
this.db.object('warehouse/wares').contains(["id1", "id27", "id533"]).valueChanges();
I saw query limits in Angular Fire like equalTo and etc. but every is for list. I'm totally confused. Is there anyone who can help me? Maybe I'm making mistakes in the design of the app structure. If so, I am asking for clarification.
Because you are saving the ids inside user try this way.
wares: Observable<any[]>;
//inside ngOnInit or function
this.wares = this.db.list('users/currentUserId/wares').snapshotChanges().map(changes => {
return changes.map(c => {
const id = c.payload.key; //gets ids under users/wares/ids..
let wares=[];
//now get the wares
this.db.list('warehouse/wares', ref => ref.orderByChild('id').equalTo(id)).valueChanges().subscribe(res=>{
res.forEach(data=>{
wares.push(data);
})
});
return wares;
});
});
There are two things you can do. I don't believe Firebase allows you to query for multiple equals values at once. You can however loop over the array of "ids" and query for each one directly.
I am assuming you already queried for "waresIds" and you've stored those ID's in an array named idArray:
for id in idArray {
database.ref('warehouse/wares').orderByChild('id').equalTo(id).once('value').then((snapshot) => {
console.log(snapshot.val());
})
}
In order to use the above query efficiently you'll have to index your data on id.
Your second option would be to use .childChanged to get only the updated data after your initial fetch. This should cut down drastically on the amount of data you need to download.
Yes , you can get exactly data that you want in firebase,
See official Firebase documents about filtering
You need to get each waresID
var waresID = // logic to get waresID
var userId = // logic to get userId
var ref = firebase.database().ref("wares/" + userId).child(waresID);
ref.once("value")
.then(function(snapshot) {
console.log(snapshot.val());
});
this will return only data related to that waresID or userId
Note: this is javascript code, i hope this will work for you.

Fetch all emails across all Gmail contact groups

I am trying to fetch all the emails from the user contacts using JS library.
Setup
1.) Initialised the gapi client using
gapi.client.init({
apiKey: config['google']['apiKey'],
discoveryDocs:
["https://www.googleapis.com/discovery/v1/apis/people/v1/rest"],
clientId: config['google']['appId'],
scope: "https://www.googleapis.com/auth/contacts.readonly"
})
2.) After the user grants permission, I try to fetch the contact details
gapi.client.people.people.connections.list({
'resourceName': 'people/me',
'pageSize': 500,
'personFields': 'names,emailAddresses'
}).then((response) => {
let connections = response.result.connections;
console.warn(connections);
})
3.) From step 2, I get zero connections.
However, when I perform
gapi.client.people.contactGroups.list()
I get following response
{
"contactGroups": [
{
"resourceName": "contactGroups/all",
"groupType": "SYSTEM_CONTACT_GROUP",
"name": "all",
"formattedName": "All Contacts",
"memberCount": 13
},
...
],
"totalItems": 9,
"nextSyncToken": "EJjRiq3lnNYC"
}
From the response, I can see that in contactGroups/all group, I have 13 contacts and in my account i can see the same number of contacts.
So, what is the proper way to get all the contacts across all the contact groups using JS library?
I've tried using gapi.client.people.people.connections.list and successfully got 200 response. I also don't get equal values.
Using gapi.client.people.people.connections.list, here is the response:
....
],
"nextSyncToken": "^***",
"totalPeople": 19,
"totalItems": 19
}
While in gapi.client.people.contactGroups.list(),
{
"resourceName": "contactGroups/all",
"groupType": "SYSTEM_CONTACT_GROUP",
"name": "all",
"formattedName": "All Contacts",
"memberCount": 155
},
Be noted that people.connections.list only provides a list of the authenticated user's contacts merged with any connected profiles. While contactGroups.list lists all contact groups owned by the authenticated user. Members of the contact groups are not populated.

Categories

Resources