Access a specific part of Firestore snapshot object - firebase

I am new to firestore need to access a specific path in my snapshot from firestore(onSnapshot). I console-logged the snapshot and got the object, now I know what I want to access, but I don't know how. I tried to access it in various ways(below console log in then is a dumb way to access it, and it doesn't work) Could you please give me some clues on how to access it?
firebase.firestore()
.collection('collectionOne')
.doc(postId)
.collection('collectionTwo')
.doc(userId)
.onSnapshot((snapshot) => {
console.log(snapshot)
const data = snapshot.e._.S_.path.segments[1] //THIS, I DONT KNOW HOW
})
Object :

I'm not sure what you realy want to get but here you have an example how to get the data, id and ref of the document you are listening to:
firebase
.firestore()
.collection("collectionOne")
.doc(postId)
.collection("collectionTwo")
.doc(userId)
.onSnapshot((snapshot) => {
console.log("data", snapshot.data());
console.log("ID", snapshot.id);
console.log("reference", snapshot.ref);
});

Related

why when retrieving data from my firestore database do i get &*nbsp; instead of space and how do i fix this?

I am using a reactjs app that runs firebase firestor.
why when retrieving data from my firestore database do i get   instead of space and how do I fix this?
This is the output I retrieved from firestore.
to give help to expolain how to replicate this.
first i put it int he database.
It appeared just as it does in the picture.
Then i took it out of the database.
this was don through an input field where I typed in the words given./
THen it was taken out through the get().then(doc => doc.data() process needed to remove anything from the firestore datadbase.
as the only problem is in the removal part
to remove:
const [data, setData] =useState({BIo:""});
firebase.Firestore().collection("contractors").doc(id).get().then((doc) => {
if (doc.exists) {
console.log("Document data:", doc.data());
setData(doc.data());
return(<div> {data.bio} </div>)
Not sure whats cause that, it is weird. you might want to take a look at how you're handling inputs.
this could a temp fix.
var textWithNBSpaceReplaced = originalText. replace(/ /g, ' ')

Unable to fetch data from Firebase Firestore in react native

I am trying to GET data from Firestore but I cannot see data coming. I am building a react-native app. I am using react-native-firebase.
I also tried Transactions method from react-native-firebase documentation. But nothing is working.
Here' my code:
firebase.firestore().collection('users').doc(uid)
.get()
.then((doc)=>{
console.log(doc)
console.log(doc.data().shoppinglist)
})
.catch(e => console.log(e));
Console logging .get() gives me a Promise.
I am getting the Promise like this:
Promise {_40: 0, _65: 0, _55: null, _72: null}
_40: 0
_55: null
_65: 0
_72: null
But .then() doesn't executes as the two console.log() ain't logging anything.
Please help me out here. Quite new with Firebase.
After some digging in Firebase Documentation, I found out a solution.
Collection references and document references are two distinct types of references and let you perform different operations. For example, you could use a collection reference for querying the documents in the collection, and you could use a document reference to read or write an individual document.
Therefore, Replacing firebase.firestore().collection('users').doc(uid) with firebase.firestore().doc(`users/${uid}`) solved my problem.
For dummies in firebase like me, if you want a custom document id, you have to specify it when writing data to firestore
import firestore from '#react-native-firebase/firestore';
firestore()
.collection('Users')
.doc('ABC')
.set({
name: 'Ada Lovelace',
age: 30,
})
.then(() => {
console.log('User added!');
});
Then you can get it by
import firestore from '#react-native-firebase/firestore';
const user = await firestore().collection('Users').doc('ABC').get();
For reference: https://rnfirebase.io/firestore/usage#writing-data

Firebase query download the whole database. Why?

I try to download and show only specific data from the Realtime Database. I have the following code:
getUserPlatformIos() {
this.dataRef = this.afDatabase.list('data/users', ref => ref.orderByChild('meta/platform').equalTo('ios'));
this.data = this.dataRef.snapshotChanges().map(changes => {
return changes.map(c => ({ key: c.payload.key, ...c.payload.val() }));
});
return this.data;
}
My firebase database structure
Firebase rules
Why firebase does download the whole database if I query before? This causes very long loading times and a lot of downloaded data....
Indexes need to be defined at the place where you the query. Since you run the query on data/users, that's where you need to define your index:
"users": {
".indexOn": "meta/platform"
}
This defines an index on users, which has the value of the meta/platform property of each user.
Note that the log output of your app should be showing an error message with precisely this information. I highly recommend checking log output whenever something doesn't work the way you expect it to work.

Firestore Realtime Listener equivalent of "Child_Added"

I am trying to figure out a solution for the Firestore realtime listeners. I know you can listen to changes and in onSnapshot see what was added, removed, changed.. but is there a way to just listen to additions?
I don't like how anytime there is a change in data, or a new document is added, the query retrieves every single piece of data.. Feels like unnescary data transfer.. especially if you were using the application on a 3G Network
Is that a legitimate concern? or is the query returning negligible data? I just want to get the "new" additions to the collection
Have you tried this?
exports.createUser = functions.firestore
.document('users/{userId}')
.onCreate((snap, context) => {
// Get an object representing the document
// e.g. {'name': 'Marie', 'age': 66}
const newValue = snap.data();
// access a particular field as you would any JS property
const name = newValue.name;
// perform desired operations ...
});

Firebase Firestore query with related document references

I'm trying to model "memberships" with Firestore. The idea is that there are companies, users and then memberships.
The memberships collection stores a reference to a company and to a user, as well as a role as a string, e..g admin or editor.
How would I query to get the users with a certain role for a company?
This is what I currently have with some basic logging.
const currentCompanyID = 'someid';
return database
.collection('memberships')
.where('company', '==', database.doc(`companies/${currentCompanyID}`))
.where('role', '==', 'admin')
.get()
.then(snap => {
snap.forEach(function(doc) {
console.log(doc.id, ' => ', doc.data());
const data = doc.data();
console.log(data.user.get());
});
})
.catch(error => {
console.error('Error fetching documents: ', error);
});
data.user.get() returns a promise to the user, but I'd have to do that for every user which seems inefficient?
What would be the best way to approach this?
Your code is close to what you want, but there are two issues:
Your where() clause can't compare a field with a document reference, because Firestore is a classic denormalized datastore. There aren't ways to strongly guarantee that one document refers to another. You'll need to store document IDs and maintain consistency yourself. (Example below).
Queries actually return a QuerySnapshot, which includes all the docs that result from a query. So you're not getting one document at a time — you'll get all the ones that match. (See code below)
So a corrected version that fits the spirit of what you want:
const currentCompanyID = '8675309';
const querySnapshot = await database
.collection('memberships')
.where('companyId', '==', currentCompanyID)
.where('role', '==', 'admin')
.get(); // <-- this promise, when awaited, pulls all matching docs
await Promise.all(querySnapshot.map(async snap => {
const data = doc.data();
const user = await database
.collection('users')
.doc(data.userId)
.get();
console.log(doc.id, ' => ', data);
console.log(user);
});
There isn't a faster way on the client side to fetch all the users that your query refers to at once -- it's part of the trouble of trying to use a denormalized store for queries that feel much more like classic relational database queries.
If this ends up being a query you run often (i.e. get users with a certain role within a specific company), you could consider storing membership information as part of the user doc instead. That way, you could query the users collection and get all the matching users in one shot.

Resources