How to get fields in a firestore document? - javascript

I am working on some Cloud functions that works with Firestore. I am trying to get a list of fields of a specific document. For example, I have a document reference from the even.data.ref, but I am not sure if the document contains the field I am looking at. I want to get a list of the fields' name, but I am not sure how to do it.
I was trying to use Object.keys() method to get a list of keys of the data, but I only get a list of number (0, 1...), instead of name of fields.
I tried to use the documentSnapShot.contains() method, but it seems doesn't work.
exports.tryHasChild=functions.firestore.document('cities/{newCityId}')
.onWrite((event) =>{
if (event.data.exists) {
let myRef = event.data.ref;
myRef.get().then(docSnapShot => {
if (docSnapShot.contains('population')) {
console.log("The edited document has a field of population");
}
});

As the documentation on using Cloud Firestore triggers for Cloud Functions shows, you get the data of the document with event.data.data().
Then you can iterate over the field names with JavaScript's Object.keys() method or test if the data has a field with a simple array check:
exports.tryHasChild=functions.firestore.document('cities/{newCityId}')
.onWrite((event) =>{
if (event.data.exists) {
let data = event.data.data();
Object.keys(data).forEach((name) => {
console.log(name, data[name]);
});
if (data["population"]) {
console.log("The edited document has a field of population");
}
});

Related

Firebase Firestore: How to update or access and update a field value, in a map, in an array, in a document, that is in a collection

Sorry for the long title. Visually and more precise, I would like to update the stock value after a payment is made. However, I get stuck after querying the entire document (e.g. the selected one with title sneakers). Is there a way to actually query and update for example the Timberlands stock value to its value -1. Or do you have to get all data from the entire document. Then modify the desired part in javascript and update the entire document?
Here is a little snippet of a solution I came up with so far. However, this approach hurts my soul as it seems very inefficient.
const updateFirebaseStock = (orders) => {
orders.forEach( async (order) => {
try {
collRef = db.doc(`collections/${order.collectionid}`);
doc = await collRef.get();
data = doc.data();
//Here:const newItems = data.items.map(if it's corr name, update value, else just return object), results in desired new Array of objects.
//Then Update entire document by collRef.update({items: newItems})
} catch (error) {
console.error(error)
};
});
}
You don't need to get the document at all for that, all you have to do is use FieldValue.increment(), using your code as a starting point it could look like this:
collRef = db.doc(`collections/${order.collectionid}`);
collRef.update({
Price: firebase.firestore.FieldValue.increment(-1)
});
You can increment/decrement with any numeric value using that function.

How can i get an element from array by index using firestore

I want to show the users elements from the array one after another when each time the user can exit or continue to the next element. The array is part of a document in firestore. How can i query firestore to retrieve specific element by index?
How can I query Firestore to retrieve specific element by index?
If you want to get a specific element of a field of type Array of a Firestore document, you need to fetch the entire document, get the value from this Array field (which is a JavaScript Array) and then extract the desired data as you would for any JavaScript Array.
There isn't any option, with the Client SDKs, to fetch only a subset of the document fields. It is possible with the REST API, but not with the Client SDKs.
So very concretely, you would as follows:
var docRef = db.collection("cities").doc("SF");
docRef.get().then((doc) => {
if (doc.exists) {
const arrayField = doc.data().arrayField;
// arrayField is a JavaScript Array, you can use any method or property
// e.g. get index 0
const arrayFieldFirstElement = arrayField[0];
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch((error) => {
console.log("Error getting document:", error);
});

Reactnative: Query and Filter Firestore Database and save a single returned document field value in a const/var

I have setup a Firebase Firestore Database and would like to filter it for a certain field value in a document.
I have a collection called "PRD" with thousands of documents where all contain the same fields. One of these fields a Document contains is a GTIN Number (String). I am receiving this Number from a Bar Code (called data), and would like to retrieve the Medication Name (called DSCRD, a different Field in all these Documents) using the GTIN Number scanned.
I am having difficulties with retrieving the Value from the Firebase and the documentation doesn't seem to get me any further. I have tried various retrieval methods. At the moment the code for retrieval looks like this:
import { dbh } from "../firebase/config"
import firestore from '#react-native-firebase/firestore'
dbh.collection('PRD')
.where('GTIN', '==', data)
.get()
.then(documentSnapshot => {
console.log('MedData',documentSnapshot.data())
});
I am unsure how to filter the right medicament using the GTIN provided by the Barcode scanner and then save the specific field value for the description of this medicament to a variable.
Firebase is setup correctly since I am able to write whole collections and documents in it.
Here is the database structure, as you can see there is the PRD Collection with all the medicaments and every medicament containing the GTIN and DSCRD Fields:
The problem with your implementation is that you are trying to call documentSnapshot.data() after querying a collection. This is the syntax you would use if you were fetching a single document. Your current query will return a list of documents which you need to handle like this:
.then(querySnapshot => {
querySnapshot.forEach(doc => {
console.log('MedData', doc.data())
})
});
Assuming that the GTIN will fetch one unique document (will it?) then you can just use the only document returned by the query to get the name of the Medication like this:
var medName
dbh.collection('PRD')
.where('GTIN', '==', data)
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
console.log('MedData', doc.data())
medName = doc.data().DSCRD
})
});

Saving a field from firestore that is an array

I am currently working on a mobile app on React and I am having trouble understanding how to save a field from fire store that is an array.
Since I can't post images my database structure is all strings such as username, first name, etc but I have a field called follow list that is an array.
What I want to do is save the usernames from the following list into an array to later search fire store for the username's in the array, this is basically what I want to do so I can render my app's social Feed. I do know that I can probably create another subcollection and write something familiar to what I did to search for users but that was a QuerySnapShot which was overall documents not a specific one and I also know firebase creates an ID for arrays and it increases as the array gets bigger.
I do not want to end up making two more subcollections one for followers and following which I think not ideal right? My current approach is this
export const fetchUserFollowing = async (username) => {
const ref = firebase.firestore().collection('users').doc(username)
let results = []
ref
.get()
.then( doc => {
let data = doc.data()
results = data
})
.catch((err) => {
return 'an error has occurred ', err
})
}
From what I understand is that a DocumentSnapShot .get() function returns an object but what I want is to store follow list into results and then return that but I am not sure how to manipulate the object return to just give me follow List which is an array
https://rnfirebase.io/docs/v5.x.x/firestore/reference/DocumentSnapshot
link to docs

React + Firebase saving issue. Why this Hash?

Im saving my data to database, using React, like this:
export const matchesInitialCreate = (user, matches) => {
return (dispatch) => {
firebaseApp.database().ref(`/users/${user}/matches`)
.push(matches)
.then(() => {
dispatch({ type: MATCHES_INITIAL_CREATE });
});
};
};
My matches entity is a simple json with some data, divided into
matches:{ groups: {...}, knockout {...}}}
Everything looks fine, but when I push it to firebase, it is saved with a hash. Like this:
users/user/matches/CRAZY_HASH/matches/groups
But I want that it saves like this:
users/user/matches/groups
What Im doing wrong?
There are different ways to save data to Firebase Realtime Database.
Push: generates a unique key at the specified reference, and writes the given data under this new child
Set: save data to a specified reference, replacing any existing data at that path
Update: updates lower-level child values of a specified reference
The reason why you see a crazy hash is you are using the push method. If you want to set the data directly under users/{user}/matches/groups, you must use either set or update.
// Will override everything
firebaseApp.database().ref(`/users/${user}/matches`).set(matches)
// Will update specific children
firebaseApp.database().ref(`/users/${user}/matches`).update(matches)

Categories

Resources