Updating User Data in Cloud Firestore - firebase

I've been having a problem trying to update data from a logged in user. I have the uid, but there has to be a connection between the uid and the collection of users, so that the program picks the right user to update, but I don't know how to make it.
Here's what I have:
FirebaseUser loggedInUser;
final _firestore = Firestore.instance;
//
double _latitude;
double _longitude;
void getCurrentLocation() async {
try {
Position position = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
setState(() {
_latitude = position.latitude;
_longitude = position.longitude;
});
_firestore
.collection('users')
.document('${loggedInUser.uid}')
.updateData({'location': GeoPoint(_latitude, _longitude)});
} catch (e) {
print(e);
}
}
Here's what I've been getting:
E/flutter ( 9187): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(Error performing updateData, NOT_FOUND: No document to update: projects/app-#####/databases/(default)/documents/users/CGyByl58ELc0zirlVjJpv5OWAc42, null)
So it is using the right uid ("CGyByl58ELc0zirlVjJpv5OWAc42")
Here's a screenshot from the Authentication tab of Firebase:
But what I'm trying to get is the name of the collection of this user in the database:

The user id is different than the document id, that's why you get that error since no document exists with the userId. You need to use the userId as the document id:
void addUser() async{
var firebaseUser = await FirebaseAuth.instance.currentUser();
Firestore.instance.collection("users").document(firebaseUser.uid).setData(
{
"age" : 38,
}).then((_){
print("success!");
});
}
Now you will have the userId as the document id and you can update the document using the userId

Related

Update Firestore document where user_id is same as currentUser uid

I have the function that I am using to create or update customer.
I am able to successfully write to db. I created a field called user_id where I save the currentUser uid into so I can read only logged in user documents.
However, I am unable to update the documents because I know I'm probably not referencing the document the right way.
I get the following error:
flutter: Error: PlatformException(Error 5, FIRFirestoreErrorDomain, No
document to update:
What am I doing wrong?
Here's my function below:
Future createOrUpdateCustomer(Customer customer, bool isUpdating) async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
String userId = user.uid;
print('Current logged in user uid is: $userId');
CollectionReference customerRef =
await Firestore.instance.collection('customers');
if (isUpdating) {
customer.updatedAt = Timestamp.now();
customer.userId = userId;
await customerRef.document().updateData(customer.toMap());
print('updated customer with id: ${customer.id}');
print('updated customer with logged in uid: ${customer.userId}');
} else {
customer.createdAt = Timestamp.now();
DocumentReference documentReference = customerRef.document();
customer.id = documentReference.documentID;
customer.userId = userId;
print('created customer successfully with id: ${customer.id}');
await documentReference.setData(customer.toMap(), merge: true);
addCustomer(customer);
}
notifyListeners();
}
You are trying to update a nonexistent document. In this line,
await customerRef.document().updateData(customer.toMap())
You are creating a document reference with a randomly-generated id. You should explicitly set the id of the document you're updating.
I think you can update the document with conditions but the reference must be the doc id, that you see in 2nd section of firestore interface.

Flutter FirebaseUser how to access the user data

I am learning Firebase with Flutter.
Currently making an anonymous login option, here is the class I created:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// sign in anonymously
Future signInAnonymous() async {
try{
// signs in as anon user
AuthResult signInResult = await _auth.signInAnonymously();
// retruns currently signed in user, else null
FirebaseUser userFromResult = signInResult.user;
return userFromResult; // HERE: if I add .uid, the id object is displayed
}catch(e){
print(e.toString());
return null;
}
}
}
In my login page after creating an instance and using the method, when I print the result I get FirebaseUser(Instance of 'PlatformUser') insted of the user information, here is the code:
onPressed: () async {
dynamic result = await _auth.signInAnonymous();
if(result == null){print('Error signing in.');}
else{
print('Signed in successfully');
print(result);
}
How can I access the user data?
UPDATE: If I change return userFromResult; to return userFromResult.uid; the id string is returned.
I still wonder, however, how to print the full object.
Your Result inside of the onpressed is a dynamic type cast, but it is a FirebaseUser inside.
// onPressed Callback
dynamic result = await _auth.signInAnonymous();
You can change your SignIn method with the right return type and use instead of dynamic the FirebaseUser.
Future<FirebaseUser> signInAnonymous() async {
// [...]
return userFromResult; // HERE: if I add .uid, the id object is displayed
}
onPressed: () async {
FirebaseUser result = await _auth.signInAnonymous();
print(result.uid); // should contain the id
// [...]
The difference is that in version 0.13.x the user data is available, but in the version used in this example the bersion used is 0.16.x.

Flutter platform error when querying for data

Can I know how can I resolve this issue?
Flutter - PlatformException : error, Invalid document reference. Document references must have an even number of segments, but users has 1, null
The following is my code to query the name of my user.
class Auth {
FirebaseUser mCurrentUser;
FirebaseAuth auth;
final firestoreInstance = Firestore.instance;
String name = '';
String uid = "";
void getCurrentUser () async {
mCurrentUser = await auth.currentUser();
uid = mCurrentUser.uid;
print(uid);
}
void getName1() async {
if(uid != null){
DocumentSnapshot document = await Firestore.instance.collection('User').document(uid).get();
name = document.data['Name'];
}
}
Try the following:
void getName1() async {
FirebaseUser mCurrentUser = await auth.currentUser();
DocumentSnapshot document = await Firestore.instance.collection('User').document(mCurrentUser.uid).get();
name = document.data['Name'];
}
Create a local variable, and retrieve the current useruid inside the method getName1()

Flutter & Firebase: Is there a way I can return a specific field from firebase to a function?

users>user Id then:
My aim is to return the user's key from the document and then be able to use that key in other functions.
getUsersKey() async {
final uid = await getCurrentUser();
Firestore.instance.collection('users').document(uid).get();
// Then I want to return the userKey feild
}
You can write the code below:
Future<void> getUsersKey() async {
final uid = await getCurrentUser();
DocumentSnapshot snapshot =
await Firestore.instance.collection('users').document(uid).get();
userKey = snapshot.data['userKey'] //you can get any field value you want by writing the exact fieldName in the data[fieldName]
}

How to delete firebase account when user data is deleted on flutter?

is it possible to delete firebase account in authentication on flutter? if yes, how to do that? I have been search but not found the way.
Firestore.instance.collection("users").document(uid).delete().then((_){
// delete account on authentication after user data on database is deleted
});
Using flutter, if you want to delete firebase accounts together with the associated firestore user collection document, the following method works fine. (documents in user collection named by the firebase uid).
Database Class
class DatabaseService {
final String uid;
DatabaseService({this.uid});
final CollectionReference userCollection =
Firestore.instance.collection('users');
Future deleteuser() {
return userCollection.document(uid).delete();
}
}
Use Firebase version 0.15.0 or above otherwise, Firebase reauthenticateWithCredential() method throw an error like { noSuchMethod: was called on null }.
Authentication Class
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
Future deleteUser(String email, String password) async {
try {
FirebaseUser user = await _auth.currentUser();
AuthCredential credentials =
EmailAuthProvider.getCredential(email: email, password: password);
print(user);
AuthResult result = await user.reauthenticateWithCredential(credentials);
await DatabaseService(uid: result.user.uid).deleteuser(); // called from database class
await result.user.delete();
return true;
} catch (e) {
print(e.toString());
return null;
}
}
}
Then use the following code inside the clickable event of a flutter widget tree to achieve the goal;
onTap: () async {
await AuthService().deleteUser(email, password);
}
Code for deleting user:
FirebaseUser user = await FirebaseAuth.instance.currentUser();
user.delete();
To delete a user account, call delete() on the user object.
For more on this, see the reference documentation for FirebaseUser.delete().
User user = FirebaseAuth.instance.currentUser;
user.delete();
From this you can delete user

Resources