CRUD flutter firebase & UPDATING rather then creating new - firebase

i have a function that creates and add new data to the cloud firestore! i want the function to check if the documents already exist, if so update them otherwise create them!
i do not know how its done. can someone help me with this please!
thank you all in advance.
this is the function.
static void createPostMonday(Post post) {
postsRef.document(post.authorId).collection('Monday').add({
'alOne':post.alOne,
'altwo':post.alTwo,
'althree':post.alThree,
'alFour':post.alFour,
'alFive':post.alFive,
'alSix':post.alSix,
'beOne':post.beOne,
'beTwo':post.beTwo,
'beThree':post.beThree,
'beFour':post.beFour,
'beFive':post.beFive,
'beSix':post.beSix,
'likes': post.likes,
'authorId': post.authorId,
'timestamp': post.timestamp,
});
}

Related

Trouble combining streams from Firebase to display users by checkin

I'm really new to flutter and coding. I'm working on an application just like Instagram but only shows users that check in to the same location. What I am trying to achieve, is that after the user has checked in, I want to display all the users that checked in within that day. However, I am not sure about the database structure, or how to write it at all. If there is any advice on any step, I am more than happy and grateful for all the comments.
Here is what my database structure looks like.
[Database Structure][1]
I am planning to use RxDart to combine streams so that the story can be updated as a new user check-in or post a story. Here is what my application currently looks like. (Please correct me at any point if I can achieve the result by a more efficient method)
[UI of the feed][2]
I understand that my code probably is completely wrong but it is the best effort from me. Please understand.
Approach 1: I tried to follow [this][3] document but am struggling to implement it.
class CheckinsListViewModel {
CheckinsListViewModel({required this.database});
final FirestoreDatabase database;
#override
Stream<List<UserCheckins>> UserTest() {
return Rx.combineLatest2(database.userStream(), database.checkinStream(),
(List<model.User> users, List<Checkins> checkins) {
return users.map((user) {
final checkin = checkins.firstWhere(
(checkin) => checkin.uid == user.uid,
);
return UserCheckins(users: user, restaurants: checkin.rid.toString());
}).toList();
});
}
}
Approach 2
I am not sure if I can achieve something like this because approach 1 is overwhelming for me. If anyone can clarify, it'd make my day.
class CheckinsListViewModel {
CheckinsListViewModel({required this.database});
final FirestoreDatabase database;
#override
Stream<List<UserCheckins>> UserTest() {
return Rx.combineLatest2(
FirebaseFirestore.instance.collection('users').snapshots(),
FirebaseFirestore.instance.collection('checkins').snapshots(),
(AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> users,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> checkins) {
return //somehow map and return uid from each documents;
}).toList();
}
}
I am new to StackOverflow. If there is more information needed (which I believe so) please feel free to guide me. Thank you for all your responses, whether they be a criticism or a solution.
[1]: https://i.stack.imgur.com/uT06e.png
[2]: https://i.stack.imgur.com/o5542.png
[3]: https://codewithandrea.com/videos/rx-dart-by-example-combine-latest/

How to create a document if the document doesn't exist or else don't do anything?

I Wanted To Ask If It Is Possible To Make A New Document With A UID If It DOESN'T Exist But if it exists NOT To Do Anything (and if possible return an error) In Firestore. (In Modular Javascript)
And If It Is Possible How?
Note: I Already Read This Question:StackOverFlow 46888701 But It Doesn't Fit My Requirements because after creating the document I want to be able to update it too.
Edit: I Wanted To Know Without Using getDoc because when i use it acts like a read and i don't want to spend lots of my no of reads from my limit.
You should first try to get the document and check if it exists then proceed to your document set/update. See sample code below:
import { doc, getDoc } from "firebase/firestore";
const docRef = doc(db, "<collection>", "<UID>");
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log("Document exist!");
// Throws an error.
throw new Error('Document Exist!');
} else {
await setDoc(docRef, {
// Document Data
});
}
For more relevant information, check out these documentations:
Get a document
Update a document
Set a document
Edit:
If you don' t want to use getDoc then you have the option to use updateDoc, it will produce an error but you can still execute a setDoc method on the catch method. On this approach, you're doing a fail-safe practice that you're responding in the event of failure. See code below:
const docRef = doc(db, "<collection>", "<UID>");
// Produces error log if no document to update
updateDoc(docRef, {
// document data
})
.catch((error) => {
// console.log(error);
setDoc(docRef, {
// document data
});
});
According to the documentation, an update is just a write operation:
Charges for writes and deletes are straightforward. For writes, each set or update operation counts a single write.
We have established that an update is just a write operation (there's no reading involved). A write is a change in a document, since you're not changing anything because the document didn't exist then you won't be charged at all.
In web version 9, the function that can help you create a document is named setDoc(), which creates or overwrites a document at a specific document reference.
How to create a document if the document doesn't exist or else don't do anything?
If you want to achieve that, you have to check if the document already exists. If it doesn't exist, create it using setDoc(), otherwise, take no action, but do not use the updateDoc() function in this case.
Remember that the updateDoc() function helps only when you want to update some fields of a document without overwriting the entire document. If the document doesn't exist, the update operation will fail.
Edit:
According to your edited question, please note that there is no way you can know if a document exists, without checking it explicitly. You can indeed not do that check, but you'll end up overwriting the document over and over again. Please also note, that a write operation is more expensive than a read operation. So that's the best option that you have.

Firebase Firestore Data Not Visible Issue

I ran into issue where Firestore is not reflecting data on client.
Lets say when I create cart manually from Firebase Console it reflects on client side but when I create Cart from client side it does not reflects, although a empty card appears but its null. Assist me on this
Firestore Rules are Public
Data Calling Method
public async Task<ObservableCollection<T>> GetCollection(string collection)
{
var tcs = new TaskCompletionSource<ObservableCollection<T>>();
await DataStore.Collection(collection).Get()
.AddOnCompleteListener(new OnCollectionCompleteListener<T>(tcs));
return await tcs.Task;
}
Thanks
I resolved this issue on my own. While working with Firestore, I understood that if you keep any field null in Firestore, the data inside the document will not be visible. So make sure to not leave any field empty.

Is it possible to go through documents in cloud firestore to see if a value of a property is equal to a comparing one?

I have website written in plain javascript to keep daily to-do tasks and the app crashed lately because different tasks of the same date was created on accident. My question is...
how can i write an if statement that checks if a document from a collection has a property (in my case the date) that is equal to the one in the input field of my form. i guess it should check after i click submit? if it exists, creation should be denyed, if not, ok to proceed.
i am using cloud firestore by the way... many thanks in advance for the help!
First, make a query to get a document that has same date:
var query = db.collection("yourCollectionName").where("date", "==", dateInInputfield);
query.get().then(function(querySnapshot) {
if (querySnapshot.empty) {
//empty
} else {
// not empty
}
});
If empty{you can proceed}, if notEmpty{some other task already exist on same date}
If you are making an app like this, a cleaner approach will be to name the id of a document as it's date, for eg. if a task is created at timestamp of 1234567, create a document named 1234567 and inside it, store all the necessary information.
By following this approach, if you create a new task, simply fetch a document by the name in inputfield,
var docRef = db.collection("yourCollectionName").doc("date");
docRef.get().then(function(doc) {
if (doc.exists) {
//this means some other document already exists
} else {
//safe to create a new document by this date.
}
}).catch(function(error) {
console.log("Error:", error);
});

Firebase cloud functions - observe ref

I´m completely new to firebase cloud functions. I want to refer to different refs inside a cloud function and get an array with the values of these.
So for example I want to get all the fruits from ('fruits').
similar to (IOS):
ref.observe(.childAdded ... )
How do I code that?
There is currently no way to only trigger a Cloud Function when a new child node is added. Instead you will have to trigger for every write (with onWrite()) and then filter inside the code.
The Firebase documentation on using previous values has this example:
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite(event => {
// Only edit data when it is first created.
if (event.data.previous.exists()) {
return;
}
// Exit when the data is deleted.
if (!event.data.exists()) {
return;
}
...
Hmmm.... on second reading of your question, you may be looking how to read from other parts of your database inside a Cloud Function. For that you'd use the Firebase Admin SDK, of which you can find an example in this sample in the functions-samples repo:
admin.database().ref('/messages').push({original: original}).then(snapshot => {
...
})

Resources