This is the thing I want to accomplish: I'm building a web shop. The web shop has a React Front-end. The front-end fetches 5 collections from Firestore and displays all the items from the collection array on the shop page. A user selects an item on the shop page. I send the item fields such as (price, name, quantity, id) to my express server and the server makes a checkout session of the item fields. The user goes to a Stripe checkout form and is sent back to my front-end by Stripe when the payment is complete. I listen for that event on my server and when then want to update the quantity field of the item in Firestore.
But how do I query Firestore for this item? Is there a way to query Firestore with only this id field (or name field)? Some something like:
db
.collection('collections')
.where('id', '===', 1)
Or do I need to save the document id (of the collection) as a field inside the item map and also send that to Stripe? Or is there a better way to do this? I can't find anything online about this.
Here is a screenshot of Firestore.
Please forgive my beginner question. I'm still learning React, Firestore and Node.js.
First be sure you are sticking to the Firestore terminology correctly. There are collections and there are documents.
Collections you access via a path such as:
collRef = db.collection("products")
collRef = db.collection("products").where("quanity_on_hand", ">", "0")
collRef = db.collection("products").doc("12345").collection("purchase_history")
The latter instance can also be accessed via collRef = db.collection("products/12345/purchase_history").
In all the above cases you will get back a CollectionReference.
Documents you access such as:
docRef = db.collection("products").doc("12345")
docRef = db.doc("products/12345")
This returns you a DocumentReference for the document whose ID is "12345" in the collection "products".
So for your code example above, you want to use docRef = db.doc("collections/1") to get back the DocumentReference for the item you are after. (Or, alternatively, you could use: docRef = db.collection("collections").doc("1")
If you stick with the code that you have above, you'd get back a CollectionReference then you'd need to fetch the data with .get(), then extract the resulting documents (that will just be a single document), then work with that. Oh...and you will need to put an "id" field into all of your documents because the document's ID value (the "name" of the document) is not part of the document by default so if you want to use .where("id", "==", "1"), then you need to add an "id" field to your document and populate it correctly.
If you go with docRef = db.doc("collections/1"), you are querying for the document directly and will get back a reference to just that one. No need for extra fields, nor extracting a single document from a result set.
Related
I'm trying to get the real-time document fields (text and timeStamp) to be displayed from the "first" collection in firestore collection, with the use of onSnapshot. I can verify that the snapshot realtime updation is working, on addition of a new document, it does shows an update. But I cannot access the text and timeStamp in the document.
onSnapshot(collection(db, 'first'), (snapshot) => {
console.log(snapshot.text, snapshot.timeStamp);
});
It just shows undefined to me. Also, I just want to access this database, db only when the user is authenticated. So is there a way to check if the user is authenticated?
To get the data from a document snapshot, you need to call data() on it. In addition, since you're reading an entire collection, you get back a query snapshot that can contain multiple documents, which you also need to handle.
So:
onSnapshot(collection(db, 'first'), (querySnapshot) => {
querySnapshot.docs.forEach((docSnapshot) => {
console.log(docSnapshot.data().text, docSnapshot.data().timeStamp);
})
});
See the documentation on getting data from Firestore and on reading all documents from a collection for more examples like this.
I want to access a subcsription, to see if the status is active.
I have this:
const subscription = await stripe.subscriptions.retrieve({
email: 'contact#Inderatech.com',
});
res.send(subscription)
however, it doesn't let me do it like this. On the stripe docs, it says to do it like this:
const subscription = await stripe.subscriptions.retrieve(
'sub_icsb2'
);
but i won't have the subscription id unless i grab it using the customer email. So is this possible?
The API only supports retrieving an object by their id. So when you want to retrieve a Subscription you need its identifier, the sub_123.
It is not possible to retrieve a Subscription by another property today and it applies to all APIs. There are List APIs that you can use to filter specific objects. For example when you list subscriptions you can filter them for a specific Price via the price parameter.
Today, the subscription doesn't have an "email" property so there isn't a way to list subscriptions for a specific email. Usually what you want is to first find the customer(s) that have a specific email address via the email parameter and then you can list subscriptions for that specific customer via the customer parameter.
My Cloud Firestore looks like this:
users
├────random_id_1───{name, email, ...}
├────random_id_2───{name, email, ...}
...
└────random_id_n───{name, email, ...}
I want to update a document of users given I have an unique identifier for it that is NOT the random id of the document (suppose, for example, the name is unique and I want to use it as identifier).
How can I update a document identifying it by a field of it?
Firestore can only update documents for which it knows the complete reference, which requires the document ID. On your current structure, you will have to run a query to find the document. So something like:
firebase.firestore().collection("users")
.where("name", "==", "Daniel")
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(document) {
document.ref.update({ ... });
});
});
If you have another attribute that is unique, I'd always recommend using that as the IDs for the documents. That way you're automatically guaranteed that only one document per user can exist, and you save yourself having to do a query to find the document.
I currently have the following node:
Basically what I want is to search the registry by the uid parameter. What I can not understand is that they tell me that I should not do it by means of a query, so what would be the other way? I have tried with the following:
firebase
.database()
.ref('nuevosUsuario')
.child(user.uid)
.once('value')
.then(snapshot =>
console.log(snapshot.val())
);
pero me imprime en consola null
Thank you in advance, I'm new to firebase.
You JSON structure stores user information, where it stores the information for each user under a so-called push ID (a key generated by calling push() or childByAutoId()). You're trying to query this structure to find the user based on their UID, which is stored in a property for each user. The only way to do this is by using a database query, like:
firebase.database()
.ref('nuevosUsuario')
.orderByChild("uid")
.child(user.uid)
.once('value')
.then(snapshot => {
snapshot.forEach(userSnapshot => {
console.log(snapshot.val())
});
});
You need to perform a loop here, since there may be multiple nodes that have the correct value for their UID property.
If there can logically be only one node for each user under nuevosUsuario, it is better to store the user information under the user's UID as a key, instead of using a push ID.
So you'd get a structure like:
"nuevosUsuario": {
"SYFW1u808weaGEf3fW...": {
"appellido": "PRUEBA",
"correo": "..."
...
}
}
This has a few advantages:
There can only be one child node for each user, since keys are by definition unique in a collection.
You can now get the user given their UID without a query, which is both faster and simpler in code. As in: the code in your question would work for this structure.
So I've been using Firebase as a database for my website (this is a web based project, using HTML, CSS and JS) and I'm running into a problem retrieving data from it.
Basically this site allows users to create a profile for a character (they can fill in the name, the characters stats etc...) and when they click submit, it'll save the values they filled out to the database.
The values are saved perfectly fine, but when I go to retrieve the data the command doesn't seem to do anything.
So in order to get the profiles, I've been trying to use this bit of code to get whatever is stored at the specified .ref(path):
var uid = firebase.auth().currentUser.uid;
var getChar = firebase.database().ref('/users/' + uid + '/chars/').orderByKey();
Which according to the Firebase docs should return a list of keys at the path that I specified in .ref(). However whenever I try to access whatever is in the var, it just gives me the string that contains a link to the database that looks like this:
https://#mydatabaseurlhere.firebaseio.com/users/uid/chars
Where #mydatabaseurlhere is the url I created on the Firebase app, and the uid is the authenticated user's ID.
I've been reading the docs, and its telling me that the above code should return a list of whatever is at the path that I specified, but so far it just gives me a link. Is there something I've been missing from the Docs that'll allow me to access whatever data is currently in the database? Because I've tried to take a snapshot using .once() to no avail either. I've also set the rules on /users/ to allow anyone to read/write to the database but I'm still not able to access the data (or maybe I am accessing, I'm just missing how to retrieve it).
Either way, I'm wondering how one can go about accessing this data, as I'm extremely confused as to why I can't seem to retrieve the data that has been successfully written to the database.
You're defining a query. But that doesn't yet retrieve the data.
To retrieve the data, you need to attach a listener. For example:
var uid = firebase.auth().currentUser.uid;
var getChar = firebase.database().ref('/users/' + uid + '/chars/').orderByKey();
getChar.on('value', function(snapshot) {
snapshot.forEach(function(child) {
console.log(child.key, child.val());
});
});