Firestore: Conditional query not executed - javascript

This logs the snapshot:
const db = firebase.firestore();
const collection = db.collection(`companies/${company}/meetings`);
let query = collection.where('start', '>=', new Date());
const snapshot = await query.limit(10).get();
console.log(snapshot);
This doesn't:
const db = firebase.firestore();
const collection = db.collection(`companies/${company}/meetings`);
let query = collection.where('start', '>=', new Date());
if (branch) {
query = query.where('branch', '==', branch);
}
const snapshot = await query.limit(10).get();
console.log(snapshot);
Does anyone know why?

Since you are combining the '>=' and '==' operators, Firestore needs to build an index for this query.
If you catch the error with a try/catch block, you will see the corresponding error, and, even better, the error message includes a direct link to create the missing index in the Firebase console.
See the doc here for more details on indexing in Firestore.

Related

Collection references must have an odd number of segments

I am currently encountering this problem in my react native app using Firebase:
Collection references must have an odd number of segments
I've seen similar cases in stackoverflow but wasn't able to solve my problem. Here is my code :
const getData = async () => {
console.log(user.uid + " 🚧🚧🚧")
const col = collection(db, "users", user.uid)
const taskSnapshot = await getDoc(col)
console.log(taskSnapshot)
}
getData()
I am trying to open my document with the document reference (user.uid) but I am getting this error : Collection references must have an odd number of segments
Hope you can help me solve this problem.
The getDoc() takes a DocumentReference as parameter and not a CollectionReference so you must use doc() instead of collection().
import { doc, getDoc } from "firebase/firestore"
const docRef = doc(db, "users", user.uid)
const taskSnapshot = await getDoc(col)
console.log(taskSnapshot.data() || "Doc does not exists")
Also checkout Firestore: What's the pattern for adding new data in Web v9?
replace this
collection(db, "users", user.uid)
with this
collection(db).document("users").collection(user.uid)

getDoc from firestore without searching for specific uid

I'm having an issue getting the collection info. Using this code, I could only get the doc with a specific uid.
const snapShot = doc(db, 'Files', 'someUID');
const getSnapShot = await getDoc(snapShot);
console.log(getSnapShot.data());
I used this code to get all of the collection items but threw an error.
const snapShot = collection(db, 'Files');
const getSnapShot = await getDoc(snapShot);
console.log(getSnapShot.forEach(doc => console.log(doc.data()));
Uncaught (in promise) FirebaseError: Expected type 'wc2', but it was: a custom gc2 object
Q: How do I make it work?
To get all documents from a collection or documents that match a query you should use getDocs() instead of getDoc() that is used to fetch a single document as the function name suggests.
const snapShot = collection(db, 'Files');
const getSnapShot = await getDocs(snapShot);
console.log(getSnapShot.forEach(doc => console.log(doc.data()));

firebase.firestore() shows bizarre data and not my actual documents from the database/

I am querying firebase firestore by...
let database = firebase.firestore();
let places = database.collection("place");
console.log("places", places);
now the logged data is bizarre and not the actual documents..
here is a picture of the log...can you please advice regarding tackling this ?
If you want to retrieve all items in your collections called "place" you can do something like this:
let database = firebase.firestore();
let places = database.collection("place");
const querySnapshot = places.get()
// You can make an empty array to eventually push the items into
const collectionArray = []
querySnapshot.forEach((doc) => {
const data = doc.data()
collectionArray.push(data)
}).catch(function(error) {
console.log("Error getting documents: ", error);
})
console.log('collectionArray:',collectionArray)
}
Your code hasn't actually executed any query yet. All it's done is build a Query object.
If you want to execute the query, call get() on it, and handle the results as shown in the documentation.
let database = firebase.firestore();
let query = database.collection("place");
query.get()
.then(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
console.log("document", documentSnapshot.data());
})
})

Firestore specific data read does not work with variable but works with static value

I am trying to query specific document from firestore database. The problem seems to be that If I add the doc(id) statically, it works but with variable it does not even tho the variable has correct and exact same value I tested statically with.
The document I am trying to retrieve is a User node/document under /users collection.
read is the function I am using to retrieve the data:
export default class GenericDB {
constructor(collectionPath) {
this.collectionPath = collectionPath
}
/**
* Read a document in the collection
* #param id
*/
async read(id) {
const result = await (await firestore())
.collection(this.collectionPath)
.doc(id)
.get()
const data = result.exists ? result.data() : null
if (isNil(data)) return null
this.convertObjectTimestampPropertiesToDate(data)
return { id, ...data }
}
}
This is my vuex action:
getUser: ({ commit }, userId) => {
return new Promise((resolve, reject) => {
//usin UsersDB() instead of Generic() because my UsersDB() has constructor with correct path to /users
new UsersDB().read(userId).then(user => {
//Empty user if userId value is from variable and not empty if I use static value
resolve(user)
})
})
}
And I do call it out:
mounted() {
if (this.id) {
//getUser function is declared inside ...mapActions('authentication', ['getUser'])
this.getUser(this.id)
}
}
Update 1: I did compare static string against my variable with logical operator and it turns out that the variable userId has space at the end. I have no clue why and where does it come.
There is no error just empty data. I can not see what can be wrong with this simple query. Any help is appreciated!
Try making connection this way instead of directly using it.
const db = firebase.firestore();
async function read(id) {
const result = await db
.collection(this.collectionPath)
.doc(id)
.get()
const data = result.exists ? result.data() : null
if (isNil(data)) return null
this.convertObjectTimestampPropertiesToDate(data)
return { id, ...data }
}
Generally, standard format we mostly use to get document is :
const db = firebase.firestore();
const result = await db
.collection("collection_name")
.doc("document_id")
.get();
I hope this helps you. Please let me know for any issues.
After you edited the question I tried passing a valid variable and I am getting response. This is giving me data of document.
//Firebase
const admin = require("firebase-admin");
let serviceAccount = require("./firebase.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
let db = admin.firestore();
//End of Firebase
id = "lWxkvqZnBxNRke4SFyJj"
async function getData(id) {
const result = await db
.collection("users")
.doc(id)
.get();
data = result.data()
console.log(data)
return data
}
getData(id)
It turned out that the userId was not exatctly the same if I compared them with logical operator. The variable version had space at the end.
So the solution was to use userId.replace(/\s/g, '')
I was facing the same issue recently. Then I figured out that my string has quotes. The following code solved the problem.
roomId.trim().replace(/['"]+/g, '')

How to get a mongodb query to frontend code

I'm trying to query a MongoDB database and then display it to the frontend code/page.
Here's what I got so far. Note, it does sucessfully console.log() the search results on the backend just not on the frontend.
Backend File
export async function searching() {
let output = "";
const mongo = require('mongodb').MongoClient
const url = "mongodb+srv://[protected..]";
await mongo.connect(url, {useNewUrlParser: true,useUnifiedTopology: true}, (err, client) => {
const db = client.db('domains')
const collection = db.collection('domains')
collection.find().toArray((err_again, items) => {
output = items
console.log(output)
return output
})
})
}
Frontend
export async function button2_click(event) {
let output = await searching()
console.log(output)
}
Note I'm doing this in Wix code so some of the synctax front-end syntax might be different.
The "console.log(output)" gets an undefined response.
When I console log the backend file the "console.log(output)" successfully outputs the array, but it's now showing on the frontend console.
Please help I've been spending hours on this with no luck. THANK YOU!
I was able to figure this out so I figured I would post the answer here:
export async function findRecord(database, sub_db, query) {
let output = "";
const mongo = require('mongodb').MongoClient
const url = "mongodb+srv://...";
const client = await mongo.connect(url, {useNewUrlParser: true,useUnifiedTopology: true});
const db = client.db(database)
const collection = db.collection(sub_db)
const items = await collection.find(query).toArray();
client.close()
return items;
}

Categories

Resources