I keep getting this error within the terminal when that code is supposed to execute
Local module descriptor class for com.google.android.gms.providerinstaller.dynamite not found.
The rules allow for everything to be updated
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write, create, update: if request.auth != null;
}
}
}
This is the code that is supposed to increment and return the points
void incrementPoints(int points_) {
final uid = user!.uid;
db
.collection("users")
.doc(uid)
.update({"score": FieldValue.increment(points_)});
}
Future<int> getPoints() async {
final uid = user!.uid;
DocumentSnapshot snapshot = await db.collection("users").doc(uid).get();
Map<String, dynamic> data = snapshot.data() as Map<String, dynamic>;
final points = data['score'];
if (points is int) {
return points;
} else if (points == null) {
return 0;
}
return 0;
}
I have tried re downloading the emulator with google play services along with deleting the old firebase project and making a new one.
Related
I get this exception using Firebase Firestore. I have tried everything and every possible rule for Firestore but still does not work.
What I'm trying to do is, getting a user from a collection and then checking the value of it with Riverpod state manager.
Getting a user from Firestore:
Future<UserModel?> getUserData() async {
DocumentSnapshot<Map<String, dynamic>> userData =
await firestore.collection('users').doc(auth.currentUser?.uid).get();
UserModel? user;
if (userData.data() != null) {
user = UserModel.fromMap(userData.data() as Map<String, dynamic>);
}
return user;
}
Using a provider to get the value and then returning a screen:
home: ref.watch(userDataAuthProvider).when(
data: (user) {
if (user == null) {
return const RegisterScreen();
} else {
return const HomeScreen();
}
},
error: (err, trace) {
return Center(child: Text(err.toString()));
},
loading: () => const CircularProgressIndicator(),
),
Firestore rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
Open your firebase console and Go to Firebase Datastore and make changes below in Rules.
Edit Rules and change like this
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
I Hope this things are solve your issue.
https://i.stack.imgur.com/fkivo.png
I am trying to achieve a task in which I have a List<dynamic>and its giving me multiple values on its indexes e.g. ['Me','Admin', so on....] something like this.
I cannot pass the List directly to Document ID it gives index error and I don't if it will still give error or not If the List give data in string List<String>
I want to loop around the indexes of this list and pass it to Firebase collection's document id to get multiple data's of the users. For example on list's index 0 there's Me coming for myself and on index 1 there's Admin coming. Both have their respective data stored in Firestore collection with their own document id's Me and Admin. I want it to be checked on the runtime the app will check if its Me or Admin or Some other index value
Here's my code of the list and the firestore I'm trying to achieve.
List<dynamic> clientcodes = [];
void getclientcodes() async {
final clientcode = await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser!.email)
.get()
.then((clientcode) {
return clientcode.data()!["clientcode"];
});
setState(() {
if (clientcode != null) {
clientcodes = clientcode;
} else if (clientcode == null) {
setState(() {
const SpinKitSpinningLines(size: 100, color: Color(0xFF25315B));
});
}
});
}
Firestore:
Future getdatastatus() async {
DocumentSnapshot result = await FirebaseFirestore.instance
.collection("Statements")
// .doc("If I hardcode it the value of index 0 or 1 it works fine")
.doc(portfolionames.toString()) // This is area of issue
.get();
if (result.exists) {
print("Yes");
} else {
print("No");
}
}
You can insert getdatastatus() inside a loop, and let it get the index automatically by comparing it with any value you want it, see this:
Future getdatastatus() async {
for (var item in clientcodes) {
String docId = item.id;
if (docId == 'X' || docId == 'Y') {
DocumentSnapshot result = await FirebaseFirestore.instance
.collection("Statements")
.doc(docId)
.get();
if (result.exists) {
print("Yes");
} else {
print("No");
}
}
}
}
Hope that work with you!!
Update
In the first section of your code, I think there is a problem..
You can create the list out of the firestore streaming, then add the coming data to the list of model, after that you can loop it to take the value you want.
Class Database{
List<TestModel> clientcodes = [];
getclientcodes() {
return FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser!.email)
.snapshots()
.listen((event) {
clientcodes.add(TestModel.fromMap(event));
setState(() {
if (clientcode != null) {
clientcodes = clientcode;
} else if (clientcode == null) {
setState(() {
const SpinKitSpinningLines(size: 100, color: Color(0xFF25315B));
});
}
});
});
}
}
class TestModel {
late String name;
late String description;
TestModel({
required this.name,
required this.description,
});
TestModel.fromMap(DocumentSnapshot data) {
name = data['name'];
description = data['description'];
}
}
I'm learning Flutter and as an exercise I'm interfacing with Firebase (I'm also new to this - my first encounter).
In the exercise when we register a new user we create a document for the newly registered user with default values.
A new user is getting registered but neither collection nor document is getting created.
I had created the Cloud Firestore is Test Mode. I've attached the rules bellow.
Rules :
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if
request.time < timestamp.date(2021, 3, 4);
}
}
}
auth.dart
//Resgister using email and password
Future registerWithEmailPassword(
{#required String email, #required String password}) async {
try {
Firebase.UserCredential resut = await _auth
.createUserWithEmailAndPassword(email: email, password: password);
Firebase.User user = resut.user;
//create a new document for user with uid
await DatabaseService(uid: user.uid).updateUserData(
sugars: '0',
name: 'new crew member',
strength: 100,
);
return _userFromFirebase(user);
} catch (e) {
//print(e.toString());
return e.toString();
}
}
database.dart
import 'package:cloud_firestore/cloud_firestore.dart';
class DatabaseService { final String uid; DatabaseService({this.uid});
//colection reference
final CollectionReference brewCollection =
FirebaseFirestore.instance.collection('brews');
Future updateUserData({String sugars, String name, int strength}) async {
return await brewCollection
.doc(uid)
.set({'sugars': sugars, 'name': name, 'strength': strength}); } }
}
I added a break-point and checked the data in updateUserData, the data is proper.
Their was an issue with the Firebase plugin.
MissingPluginException(No implementation found for method DocumentReference#set on channel plugins.flutter.io/firebase_firestore)
I updated by pubspec.yaml to have the latest version file then run the following commands
flutter clean
flutter packages get
Hi there I'm having some trouble to retrieve data from Firestore;
I created a class User for getting all the information for my app.
User Class:
class User {
String id;
String displayName;
String email;
String pictureURL;
String gender;
DateTime dateOfBirth;
User(fbauth.User user) {
id = user.uid;
displayName = user.displayName;
email = user.email;
pictureURL = user.photoURL;
// setting info
DocumentSnapshot resl = FirestoreUtil.read("AdditionalUserInfo", user.uid);
gender = resl.data()['gender'];
dateOfBirth = (resl.data()['date of birth'] as Timestamp).toDate();
}
FirestoreUtils class:
class FirestoreUtil {
static DocumentSnapshot read(String collection, String document) {
FirebaseFirestore.instance
.collection(collection)
.doc(document)
.get()
.then((DocumentSnapshot snapshot) {
if(snapshot.exists){
return snapshot;
}else{
print("no data found");
}
});
}
}
After I return the snapshot, it gets null. But if I do this it prints out the correct values:
class FirestoreUtil {
static DocumentSnapshot read(String collection, String document) {
FirebaseFirestore.instance
.collection(collection)
.doc(document)
.get()
.then((DocumentSnapshot snapshot) {
if(snapshot.exists){
print(snapshot.data);
}else{
print("no data found");
}
});
}
}
I tried literally everything but I couldn't figure out. Could someone help? I cannot imagine that is that hard to retrieve data inside a class.
It's probably Future(async/await) problem. You are returning value inside Future, you can get this value inside another then() etc.
class FirestoreUtil {
static DocumentSnapshot read(String collection, String document) async {
// You can directly return it too without assigning it to result variable
var result = await FirebaseFirestore.instance
.collection(collection)
.doc(document)
.get();
return result;
}
}
There is data() method for DocumentSnapshot, you can use result.data() and check if it's null, isEmpty etc.
I wrote this function with async/await but if you need Future and didn't want to wait operation to be finished, you can directly return
FirebaseFirestore.instance.collection(collection).doc(document).get();
and you can use then() after you get the Future.
I have a Flutter project that's using the cloud_firestore plugin for data access. Once a user authenticates to the application, what do I need to do to set that as the authentication used by the Firestore client? For example, I just have these basic rules enabled:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}
match /users/{userId}/{document=**} {
allow read, update, delete, create: if request.auth.uid == userId;
}
match /ingredients/* {
allow read, create: if request.auth.uid != null;
}
match /units/* {
allow read, create: if request.auth.uid != null;
}
match /recipes/* {
allow read, create, update: if request.auth.uid != null;
}
}
}
As soon as I enabled those rules, every request from my Flutter app started failing. If I test the Firestore rules with the little "simulator" they have, they work as expected, so the authentication does not appear to be getting set correctly from the Flutter app side.
EDIT: Adding some code samples.
I have authentication code that uses Google Auth, so when the user logs in it looks like this:
class Auth implements AuthService {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
Future<String> signInWithGoogle() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final FirebaseUser user = await _firebaseAuth.signInWithCredential(credential);
return user.uid;
}
I've verified that the user is being authenticated properly.
Then, when accessing Firestore, something like:
DocumentSnapshot userSnapshot = await Firestore.instance
.collection('users')
.document(userId)
.collection('shoppingLists')
.document(listName)
.get();
I've followed all of the guides to add Firebase and Firestore to my app, and I didn't see anything specific about setting the currently authenticated user as the user that's making the Firestore requests, so I feel like I'm missing something there. Is there something I'm supposed to be doing when making the Firestore queries to pass in the current user?
The answer is to not user Firestore.instance as this gives you an instance disconnected from your Firebase app;
instead use create you Firebase app providing all the keys, then authenticate against that app, and then create a Firestore instance against that app. There's no way to explicitly pass the user, but the code internally uses some logic to figure out user that's been authenticated against your created app. Here's the code I used:
Future<void> _authenticate() async {
FirebaseApp _app = await FirebaseApp.configure(
name: 'some-name',
options: FirebaseOptions(
googleAppID: 'some:id',
gcmSenderID: 'sender',
apiKey: 'api-key-goes-here',
projectID: 'some-id',
),
);
final _auth = FirebaseAuth.fromApp(_app);
final _result = await _auth.signInAnonymously();
setState(() {
app = _app;
auth = _auth;
user = _result.user;
store = Firestore(app: app); //this is the code that does the magic!
});
}
as for the serverside rule configuration - refer to #cloudwalker's answer
For me, it wound up being an issue with how I had my firestore rules set up. This is what I have now, and it works well:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow create: if isAuthenticated();
}
match /users/{userId} {
allow read, update: if isOwner(userId);
}
match /users/{userId}/{document=**} {
allow read, write: if isOwner(userId);
}
match /categories/{document=**} {
allow read: if isAuthenticated();
}
match /config/{document=**} {
allow read: if isAuthenticated();
}
}
function isAuthenticated() {
return request.auth.uid != null;
}
function isOwner(userId) {
return request.auth.uid == userId;
}
}
The solution is to initialize FirebaseStorage after getting authenticated user
Future<Null> main() async {
WidgetsFlutterBinding.ensureInitialized();
AppInfo.app = await Firebase.initializeApp(options: AppInfo.firebaseOptions);
}
It's easier if you have a listener
FirebaseAuth.instance.authStateChanges().listen((authUser) async {
if (authUser != null && AppInfo.authUser == null) {
AppInfo.authUser = authUser;
print("Got Firebase user: " + authUser.uid);
setState(() {
if (AppInfo.instance == null) {
AppInfo.instance =
FirebaseStorage(app: AppInfo.app, storageBucket: BUCKETGS);
AppInfo.instanceTemp =
FirebaseStorage(app: AppInfo.app, storageBucket: BUCKETTEMP);
}
AppInfo.userAuthId = authUser.uid;
streamsStartVerify();
});
} else if (authUser == null && AppInfo.authUser != null) {
print("sign out!!!");
AppInfo.authUser = null;
AppInfo.userAuthId = "";
}
});
}