Firestore not getting string from react native calendars - javascript

Hi there i am trying to insert in my firestore db, i have noticed that the data goes through but if i add it manually in the console the color of the id is diferent, is darker as you can see in the picture.
When i do a query only finds the ones i have inserted manually
In my Home.js i get the datestring value from react native calendars by wix
onDayPress={(day) => {
const dateString =day.dateString.toString()
setDateString(dateString); console.log(dateString) }}
// Initially selected day
And then in App.js i create my task with the dateString
const createTask = async (collection, data) => {
//adding data to a collection with automatic id
//const ref = await addDoc( collection(FSdb, FScollection ), data )
const ref = await setDoc(doc(FSdb, `usertasks/${user.uid}/events/${data.dateString}/items/${new Date().getTime()}`), data)
//console.log( ref.id )
}
I dont know what im doing wrong

I tried to replicate based on the screenshot and code provided.
See below for my replication:
The issue happens in two cases:
Deleting collection or document with sub collection and sub documents.
Adding collection and documents to an empty document. If you create directly something like /collection/document(1)/collection/document(2)`. You should create it in two steps:
create: /collection/document(1)
create: /collection/document(1)/collection/document(2)
The italicized document IDs shown in the UI actually doesn't exist but its still shown so that you can still navigate to the subcollections. Since there is no document, the document itself will not show up in query results. If you want any document to exist, you have to write some code to create it and give it some fields. If you never explicitly create a document, then it never exists.
You may also refer on this documentation for more information.

Related

Reducing the amount of reads in a where query

I have recently implemented firebase into my project and I have created a user collection, this collection has a document for each user and each document has about 8 fields, when my user launches the app, I am trying to pull the document that corresponds to his data, so im doing the following query:
async function getUserData() {
const _collection = collection(db, "users")
const _query = query(_collection, where("userid", "==", uniqueUserID))
const querySnapshot = await getDocs(_query)
querySnapshot.forEach((doc) => {
console.log(doc.data())
})
setLoadingStatus(false)
}
This query works and gives me the corresponding user data, but the problem is, if the user is too far down the collection, this will execute 8 reads per document until it gets to the corresponding user, I have tried to implement a cache system using a lastModified but I still need to read the document data for that field and it will end up using more or less the same amount of reads. My question is: How do I reduce the amount of read operations that get executed when im trying to compare values in the documents, I have also thought of adding an a like so a_uniqueUserID so it gets ordered alphabetically and takes the first spot of the document but it's hacky.
EDIT: Here is what my structure looks like:
I think you are misunderstanding the definition of a document and a field. When you read a document, you always get all fields out of it. The snapshot contains everything read, even if you don't use it. There is no additional cost per field, other than the storage required to hold it all. In your screenshot, you show 5 documents, and one of those documents have 8 fields.
You are probably misunderstanding the metrics in the console. When you read and write documents using the console, those are also billed as reads and writes - use of the console is not "free". What you are seeing is a combination of what your app is doing in combination with what you're doing in the console.

Currently refactoring my Firestore post data function into an array storage

Currently I have a dashboard application and when a user adds to their dashboard it does a post request to Firestore to set the data in a certain document. Here is what that code looks like:
export function createEntry(data) { // Data has a authorId key with the value of the UID
const userEntry = firestore.collection('userEntries').doc();
userEntry.set(data);
return userEntry;
}
So above, a new entry gets created with a random ID that I then use to grab the data to display later. To get this information later, I loop through all of the entries to see where the authorId matches the user that is log in to return that.
So what I am trying to do is refactor the code so that each document in 'userEntries' is the ID of the user, authorID: UID, and have it be an array where I can keep pushing items into. In return, I can just grab the user array and map over those items to display instead of looping through all my entries and checking.
What I've tried:
export function createEntry(data) {
const userEntry = firestore.collection('userEntries').doc(data.authorId);
userEntry.update({
userData: firebase.firestore.FieldValue.arrayUnion(data)
})
}
So to sum it up, I would like a way to set the document to users ID and push any future entries into their own array, in which I could easily access from the frontend to display.
Hope you can point me in the right direction, thank you!
You don't actually have to revise the original method. If you have the authorId as a field value, you can just query the data using where clause like this:
const uid = auth.currentUser.uid;
firestore.collection().where('authorId', '==', uid).get();
With this method, you are not getting the entire collection and looping through to see which one is written by the user.

Could I get 'creationTime' when I create a new document in Firestore (instead of using 'documentRef.get()' after creation and thus avoid that reading?

Goal: get the creation time of a new Firestore document in the document creation process
First I create a new document with the corresponding data newDocumentData and a field creationTime with the creation time, as shown below:
const newDocumentRef = await collectionRef.add({
...newDocumentData,
creationTime: firebase.firestore.FieldValue.serverTimestamp()
})
Then, I need the creationTime, and I follow like this...
const document = await newDocumentRef.get()
if (document.exists) {
const documentData = document.data()
}
...to finally get my documentData.creationTime.
My question is: Is there any way to get creationTime with newDocumentRef in the first step and, therefore, avoiding the rest of the process?
Thank you!
No, it is not possible with the Client SDKs, "to get the value of creationTime in the first step". FieldValue.serverTimestamp() returns a sentinel value that tells the server to assign a server-generated timestamp in the written data.
In other words the exact value for creationTime will be calculated by the server, and if you want to get this value, you need to query the database for it.
Note that, on the other hand, with the Firestore REST API, when you create a document, you get back (i.e. through the API endpoint response) a Document object that contains, among others, a createTime field.

How to get ONLY list of documents in Firebase/Firestore using reactJS

i want to ask something, i need to fetch data from firebase, BUT only the list of the documents
Like This
i've already tried, and i'm stuck (at the moment), here's my code:
this.ref3 = firebase
.firestore()
.collection("pendatang")
.orderBy("timestamp", "desc")
.limit(10);
componentDidMount = async () => {
this.unsubscribe = this.ref3.onSnapshot(this.onCollectionUpdate2);
};
onCollectionUpdate2 = (querySnapshot) => {
const tanggal = [];
querySnapshot.forEach((doc) => {
tanggal.push({
tanggal: doc.id,
doc, // DocumentSnapshot
});
});
this.setState(
{
tanggal,
},
() => {
console.log(this.state.tanggal);
}
);
};
Actually i didn't get error, i got the array but it's like didn't get any, when i use map, it didn't appear anything inside the state, this is what i got after the fetch The Image
i tried map it:
{this.state.tanggal.map((item, key) => (
<Chip
avatar={<Avatar>M</Avatar>}
label={item.tanggal}
onClick={() => this.ChipsClicked(24)}
/>
))}
and what i got:
Nothing
I really need help guys :( and I'm actually very curious about firebase, I really appreciate everyone who wants to help me :)
As shown in your Firebase console screenshot, the document is displayed with an italic font in the Firebase console: this is because this document is only present (in the console) as "container" of one or more sub-collection but it is not a "genuine" document.
If you create a subDoc1 document directly under a col1 collection with the full path doc1/subCol1/subDoc1, no intermediate documents will be created (i.e. no doc1 document).
The Firebase console shows this kind of "container" (or "placeholder") in italic in order to "materialize" the hierarchy and allow you to navigate to the subDoc1 document but doc1 document doesn't exist in the Firestore database.
So if we have a doc1 document under the col1 collection
col1/doc1/
and another one subDoc1 under the subCol1 (sub-)collection
col1/doc1/subCol1/subDoc1
... actually, from a technical perspective, they are not at all relating to each other. They just share a part of their paths but nothing else.
You can very well create subDoc1 without creating doc1.
Another side effect of this is that if you delete a document, its sub-collection(s) still exist. Again, the subcollection docs are not really linked to the parent document.
So, in your case, if you need to have genuine docs in the pendatang collection, you need to create them at the same time you create the first subcollection doc.
Also, note that Cloud Firestore has shallow reads: querying for documents in a collection doesn't pull in data from subcollections.

Firestore data modeling and angularFire

I have data model like this
Players-->root collection
Sports--->root collection
Players_Sports---root collection
I want get all the sports(Multiple sport) details or document player belongs.
For this I am using angularFireStore5
First, I am getting
Player details like this
this.db.collection('players').doc(id).get().toPromise()
Second, I am getting Player(user) linked PlayerSport
db.collection<any>('PlayerSports',ref => ref.where('playerId', '==', id) ).get().toPromise()
Third, I am trying to get Sports details based on ID'S,
db.collection<any>('sportsType', ref => ref.where('sportsType' 'in' [sportsIDs])).get().toPromise()
where SportIDs is arrary of ID that are linked in player_sports
First and Second steps works fine, but third steps is not giving any data or response
Could you please let me know where is the problem,
is it in Data model or code? my guess is that data model is not correct. Please guide me on this.
I would suggest getting the data from firebase and storing it inside a list so the app can access it later.
void getDataF(){
databaseReference
.collection("TableName")
.getDocuments()
.then((QuerySnapshot snapshot) {
snapshot.documents.forEach((f) {
iDFacList.add(f.documentID);
dbFacList.add(f.data["FieldName"]);
});
});
}
There is no sportsType field in the sportsType document as far as I can see.
If you're trying to find documents based on their SportsId field, you'll want ref.where('SportsId'....
Update
It seems that you're trying to find a document by its ID, which you can do with:
ref.doc(sportsIDs)
If you want to get multiple documents, or get a single document as a collection, you can use:
ref.where(firebase.firestore.FieldPath.documentId() 'in' [sportsIDs])

Categories