I sign in my user through google, after successfully login. I wants to create document for each user inside user_details collection and the document name should be google id. But its auto generating document name.
Is there any way to create custom document in Firestore?
Thanks in Advance
// Store data in Firestore
storeData(User user) async {
DocumentReference documentRef =
Firestore.instance.collection("user_details").document(user.id);
Firestore.instance.runTransaction((transaction) async {
await transaction.set(documentRef, user.toJson());
print("instance created");
_login.add(Result(Status.SUCCESS, "Login successful.", user));
});
}
Try this await documentRef.setData(user.toJson());
Related
I have a situation where I have a collection which contains information that displays a user profile picture, this user picture is taken from another collection's (users) document. My problem is that I add a link to the picture when I create the new document, this means that if in future the user changes the profile picture the other collection would not have that new information. Is there a way I can solve this with firebase?
I want to get the data from the other collection whenever the information in users collection is updated.
document value in the collection that needs live data
{profile-picture:"image-from-users-collection goes here"}
document value in /users collection
{user-picture:"my-pic.png"}
I want to get the data from the other collection whenever the
information in users collection is updated.
A mentioned by Mises, one standard approach is to use a Firestore Cloud Function which is triggered when the user document changes.
The following code will do the trick. I make the assumption that the document of the other collection uses the same ID than the user document.
exports.updateUserImage = functions
.firestore
.document('users/{userId}')
.onUpdate(async (change, context) => {
try {
const newValue = change.after.data();
const previousValue = change.before.data();
if (newValue['user-picture'] !== previousValue['user-picture']) {
await admin.firestore().collection('otherCollection').doc(context.params.userId).update({'profile-picture':newValue['user-picture']});
}
return null;
} catch (error) {
console.log(error);
return null;
}
});
For some time now, I have noticed that the fields of some of my firebase documents get deleted, even though I do not delete them or write any logic on my app to delete fields of a document or a document itself. This is a picture that shows a document on my firebase project, which has its fields deleted on its own.
The firebase project is connected to my flutter app, but I have not written any delete functionality.
I only update the fields occasionally with recent data.
Please, who has any idea of what's happening?
Edit
This is how I update the documents of my user collections
Future<String?> submitUpdate(User user) async{
CollectionReference userCollection = firestore.collection('users');
String? uid = await secureStorage.read(key: 'uid');
try{
//updates user doc in users collection
await userCollection.doc(uid).update(user.toMap());
return "Success";
}catch(e){
return null;
}
This is how i create the user document in the users collection.
Future<String?> saveUserCredentials(User user) async{
CollectionReference users = firestore.collection('users');
String? uid = await FlutterSecureStorage().read(key: "uid");
try{
//creates a user doc in the users collection
await users.doc(uid).set(
user.toMap()
);
return "Success";
}catch (e){
print(e);
return null;
}
I have a User model that defines the user object.
If you want to set some fields of a document, but keep existing fields, use set with SetOptions(merge: true):
FirebaseFirestore.instance
.collection(...)
.doc(...)
.set({'field1': value1, 'field2': value2}, SetOptions(merge: true));
Without this, the existing fields that are not listed in set will be not be kept, probably this happened to you.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
Future<void> userSetup(String displayName) async{
FirebaseAuth auth = FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();
CollectionReference users = FirebaseFirestore.instance.collection("Users");
users.add({
'displayName': displayName,
'uid': uid,
// 'docID': docID,
});
return;
}
Just to preface, I'm a complete beginner with Flutter.
This is what I'm using to add the collection in Firestore but I'd like to retrieve the the specific document ID and use it for further storage. Is there a method to obtain and store the document ID in the user details? I'm trying to retrieve the specific user's name when they login and display it on the homepage.
You may try this method
Preset the document id with your own, you may use the package uuid
https://pub.dev/packages/uuid
or use the user's uid as the doc id
//final docID = Uuid().v4(); //use custom uuid for doc id
//final docID = uid; //use user id as doc id
users.doc(docID).set({
'displayName': displayName,
'uid': uid,
});
Then save the docID to user device with shared_preferences for persistant storage
https://pub.dev/packages/shared_preferences
If you want to store the ID inside the document, you can first create the DocumentReference for the new document by calling CollectionReference.doc() without parameters:
CollectionReference users = FirebaseFirestore.instance.collection("Users");
var newDocRef = users.doc();
var newDocId = newDocRef.id
users.add({
'displayName': displayName,
'uid': uid,
'docID': newDocId
});
You can retrieve **firestore** doc id only when you retrieve the data using a stream builder. Take a look at the code.
Streambuilder(
stream: Firestore.instance.collection("Your collection").snapshot(),
builder: (context,snapshot) {
if(snapshot.hasData) {
List<User> users = []
for(var doc in sanpshot.data.documents) {
users.add(
new User(
name: doc.data["name"],
email: doc.data["email"]
**id: doc.documentID**
)
)
return Column(
children: users
)
}
}
}
)
In the case that you do not want to use custom IDs for your documents but instead rely on firebase auto generated IDs you can do the following.
Future<void> userSetup(String displayName) async {
FirebaseAuth auth = FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();
CollectionReference users = FirebaseFirestore.instance.collection("Users");
users.doc(uid).set({
'displayName': displayName,
});
return;
}
This will set the document ID to be the same as the users uid. The benefit of this approach is two fold.
You do not have to set an additional id property in the document.
You can now query the users collection for the specific user using the currently signed in users uid
At runtime, components are able to read the contents of their own package by accessing the path /pkg/ in their namespace. The resource() template may be used to add contents to the package that may be accessed this way.
I am in a situation where when a users makes a payment, his cart products Stored in Firestore collection (CartProducts) should be moved to new collection Called SuccessFullOrders .
So my Basic Question is how to move all documents from one collection to Firestore other Collection in Flutter
I don't Know how to write code for this in flutter.Thanks for your Answers
Here's my Code
void _onPressed()async {
final FirebaseAuth _auth = FirebaseAuth.instance;
FirebaseUser user = await _auth.currentUser();
print(user.uid);
firestorInstance.collection("users").getDocuments().then((querySnapshot) {
querySnapshot.documents.forEach((result) {
firestorInstance.collection("users").document(user.uid).collection("CartProducts").getDocuments().then((querySnapshot) {
querySnapshot.documents.forEach((result) {
//what to write here so that new documents would be created in other collection
print(result.data);
});
});
});
});
}
Currently there's no way to copy a collection into another provided by firebase officially. And, for sure, you can iterate over your previous collection & create new documents in the other.
In your case you should be doing something like:
userFirebaseInstance
.collection(NewCollection)
.document()
.setData(YourDataHere)
I have a User collection in my Firstore database, and I want to imbed a Workout collection in each document of my User collection. I can do this on the Cloud Firestore Dashboard, but how can I do this when I create a new User document in my Flutter code?
My normal code for adding a user looks like this:
Firestore.instance.runTransaction((transaction) async {
await transaction
.set(Firestore.instance.collection('users').document(uuid_), {
'grade': _grade,
'name': _name,
});
});
but I want to somehow add a Workout subcollection to my newly created User document. Thanks for any help
There is no public API to create a new subcollection. Instead a collection is created automatically when you add the first document to it.
So something like:
transaction.set(
Firestore.instance.
collection('users').document(uuid_).
collection("workouts").document("workoutid"), {
'grade': _grade,
'name': _name,
});