Can we use 'Firestore' like this? - firebase

I downloaded flutter chat app on Github and I was learning through it. The original developer used Firestore but in mine, I am getting an error "Undefined name 'Firestore'.
Try correcting the name to one that is defined, or defining the name" like this.
I search for this and I read in cloudfirestore docs we can use "FirebaseFirestore" (maybe I am wrong). I am learning to write backend with flutter and so far I did UI parts. so this is my first attempt at learning backend with flutter.
handleSignIn() async {
final res = await googleSignIn.signIn();
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
final auth = await res.authentication;
final credentials = GoogleAuthProvider.getCredential(
idToken: auth.idToken, accessToken: auth.accessToken);
final firebaseUser =
(await firebaseAuth.signInWithCredential(credentials)).user;
if (firebaseUser != null) {
final result = (await Firestore.instance
.collection('users')
.where('id', isEqualTo: firebaseUser.uid)
.getDocuments())
.documents;
if (result.length == 0) {
///new user
Firestore.instance
.collection('users')
.document(firebaseUser.uid)
.setData({
"id": firebaseUser.uid,
"name": firebaseUser.displayName,
"profile_pic": firebaseUser.photoURL,
"created_at": DateTime.now().millisecondsSinceEpoch,
});
sharedPreferences.setString("id", firebaseUser.uid);
sharedPreferences.setString("name", firebaseUser.displayName);
sharedPreferences.setString("profile_pic", firebaseUser.photoURL);
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Home()));
} else {
///Old user
sharedPreferences.setString("id", result[0]["id"]);
sharedPreferences.setString("name", result[0]["name"]);
sharedPreferences.setString("profile_pic", result[0]["profile_pic"]);
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Home()));
}
}
}
this is the error I'm getting
so can you guys explain how to solve this error?
Thank You.

I think you are missing to add cloud_firestore dependency in pubspec.yml. One more thing,
you are using latest version, use "FirebaseFirestore" instead of "Firestore".

Go to pubspec.yaml file in your flutter project.
Add this( cloud_firestore: ^0.16.0 ) below dependencies like in the image below.
You can skip this step if you use VScode. It does this automatically if you save the file after the update.
IF NOT , do flutter pub get inside your project. (this fetches the new packages added to the project, in our case cloud_firestore)
Make sure that you are able to see this import in the file you are getting the errors in.
import 'package:cloud_firestore/cloud_firestore.dart';
Next, update Firestore.instance -> FirebaseFirestore.instance in all your files where you are getting this error.

Use this code --
FirebaseFirestore.instance
.collection("users").add({"name": "Majeed"});
change Firestore with FirebaseFirestore and remove the Document and setData
replace setData with add.

Related

not able to save information to firebase

I m tring to save course details from the filled form to firebase-database by calling the below function but I m getting some error. Here is a part of my code:
Future<void>saveCourseDataToDb(courseName, courseDescription,coursePrice,yearsOfExp, cities) async{
var timeStamp = Timestamp.now().microsecondsSinceEpoch;
FirebaseUser teacher= FirebaseAuth.instance.currentUser as FirebaseUser;
CollectionReference _courses = Firestore.instance.collection('courses');
try{
_courses.document(timeStamp.toString()).setData({
'tutor': {'TeacherName': this.TeacherName, 'Teacherid': teacher.uid },
'courseName': courseName,
'courseDescription': courseDescription,
'coursePrice': coursePrice,
'yearsOfExp': yearsOfExp,
'cities': cities,
'category' : {'categoryName': this.selectedCategory, 'categoryImage': this.categoryImage},
//'certificate': certificate,
'published': false,
'courseId': timeStamp.toString(),
'courseImage': this.courseURL,
'certificate' : this.certificateURL
});
ErrorAlertDialog(message: 'Course Details saved successfully',);
}catch(e){
ErrorAlertDialog(message: '${e.toString()}',);
}
return null;
}
I get this error:
And when I declare teacher with Future I get an error related to uid, here is a picture about the same.
Any help would be really appreciated!!
FirebaseUser is a Future, which means you have to "wait" for it to arrive. Try like this
FirebaseUser teacher = await FirebaseAuth.instance.currentUser;
instead of using
Future<FirebaseUser>
use
Future<User>
FirebaseUser has been changed to User long time ago & also use await before FirebaseAuth.instance.currentUser;
hope this may work 🙋‍♂️.
try this
first update your firebase plugin to latest version and pub get
then use this
final FirebaseAuth teacher = FirebaseAuth.instance.currentUser;
inplace of Future line
hope this time it works 🤞

Cannot display any data from firestore flutter

i am developing a flutter mobile apps and i have encountered few error. which is when im running my apps, the data is not displayed. I try to retrieve the uid and specific field to be display. This is the code for the retrieve part
and this is my database where i want to retrieve the type of the user database.
This is the output from my apps output
Change your query to this.
firestore
.collection("User")
.where("uid", isEqualTo: result.id)
.where("type", isEqualTo: "teacher")
.get();
void getTeacherData(){
firestore
.collection("User")
.where("type", isEqualTo: "teacher")
.get().then((querySnapshot){
//Check here if not null
querySnapshot.docs.forEach((element){
print(element["name"]);
});
});
}
this will give you all the user who are teachers
According to this documentation, your query should be as follows:
FirebaseFirestore firestore = FirebaseFirestore.instance;
Future getTeacherData() async {
firestore
.collection('User')
.where('type', isEqualTo: 'teacher')
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((result) {
print(result['uid']);
});
});
}
Please tell us if this worked for you.

Flutter cloud firestore not updating automatically

I try to read listen to a stream from Firebase with this code:
visibleListsIds.forEach((final String listId) async {
final Stream<List<WishList>> wishListStream = sharedCollection()
.document(listId)
.snapshots()
.map((DocumentSnapshot documentSnapshot) {
log.d("updated Document Snapshot: ${documentSnapshot.data}");
return [
_getSerializers()
.deserializeWith(WishList.serializer, documentSnapshot.data)
];
});
wishListStreams.add(wishListStream);
});
Where sharedCollection() gives me access to the Firestore instance with the correct collection
I try to write to the collection, with this code
DocumentReference postRef = sharedCollection().document(wishList.listId);
firestore.runTransaction((Transaction tx) async {
DocumentSnapshot postSnapshot = await tx.get(postRef);
if (postSnapshot.exists) {
await tx.update(postRef,
_getSerializers().serializeWith(WishList.serializer, wishList));
} else {
await tx.set(postRef,
_getSerializers().serializeWith(WishList.serializer, wishList));
}
});
What happens:
I can write to Firebase but only one change at a time. When I do the next update, the last one gets reverted.
I can see the updated data only in the Firebase Console. The App does not show it and it does not show in the log at log.d("updated Document Snapshot: ${documentSnapshot.data}");.
When I modify data in the Firebase Console, I can also not see it change
BUT once I reload the App, all the Data syncs up to the current state of the Firebase Console
Anyone know why I do not get updates with the Stream?
Thanks for your help.
I use the Cloud Firestore Plugin:
cloud_firestore: ^0.13.0+1

How to use Flutter (web app) stream builder with Firestore

I see several questions and answers about Flutter for mobile that use stream builder like this:
body: new StreamBuilder(
stream: Firestore.instance.collection("collection").snapshots(),
builder: (context, snapshot) {
...
I'm trying to do the same on flutter for the web, but in my configuration, the snapshots() method is unknown, generating an exception while running (and a vscode warning beforehand). Why? Do I have an incorrect setup?
I've followed these steps which I found here and elsewhere:
1) Included firebase as a dependency in pubspec.yaml
dependencies:
flutter:
sdk: flutter
firebase: ^6.0.0
2) Included the firestore js scripts in the index.html body tag:
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-firestore.js"></script>
<script src="main.dart.js" type="application/javascript"></script>
3) In main.dart, imported firebase.dart files (using advice given here, though I'm not exactly sure which step above got me access to this package. I'm a flutter nube, if it isn't obvious)
import 'package:flutter/material.dart';
import 'package:firebase/firebase.dart' as fb;
import 'package:firebase/firestore.dart' as fs;
Having followed these steps, I can get this code working....
void main() {
if (fb.apps.length == 0) {
try {
fb.initializeApp(
apiKey: "mike",
authDomain: "myauthdomain",
databaseURL: "mydburl",
projectId: "myproductid",
storageBucket: "mystoragebucket",
);
} catch(e) {
print(e);
}
}
fs.Firestore store = fb.firestore();
fs.CollectionReference ref = store.collection("MyCollection");
ref.onSnapshot.listen((querySnapshot) {
querySnapshot.docs.forEach((doc) {
print(doc.data()); // this works!!
});
});
runApp(MyApp());
}
But, as I mentioned earlier, getting the stream builder working, all of the advice suggests that I can get a stream of snapshots by saying...
class MyList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new StreamBuilder(
stream: fb.firestore().collection('MyCollection').snapshots(),
...
The packages I have running on web don't seem to have anything like the snapshots method (or property) on a firestore collection reference. Can somebody set me straight?
I had the same issue when I tried to create a web version of my flutter mobile app which uses a lot of StreamBuilders. The following works for me:
Pubspec.yaml dependencies:
firebase_web: ^5.0.9
firebase_core: ^0.4.3+2
In your code:
import 'package:firebase_web/firestore.dart';
import 'package:firebase_web/firebase.dart';
body: new StreamBuilder(
stream: firestore().collection('collection').onSnapshot,
builder: (context, snapshot) {
...
Below I have included a list with changes that I encountered so far going from a flutter mobile app to a flutter web app:
documents = docs as in snapshot.data.docs.length
documents() = doc() as in firestore().collection('foo').doc('bar')
reference = ref as in snapshot.ref
data = data() as in snapshot.data()
The method setData from Firestore = set
The method updateData from Firestore = update(data:{'yourKey': 'yourValue',})
Hope this can help!
The querySnapshot.docs property returns a List<DocumentSnapshot>, while you need a stream for the stream property where each item on the stream is a list.
I've only needed this with the FlutterFire libraries for iOS/Android, but it should look something like this:
Stream<List<DocumentSnapshot>> getStream() async* {
fb.firestore().collection("MyCollection").onSnapshot.listen((querySnapshot) {
yield querySnapshot.docs;
}
}

Flutter: Shows some Firestore Collection with a StreamBuilder from an authenticated Firebase Auth User

My app has a collection of cards and I need to add some car to the favorites list, and I would like that each user has its own favorites collection.
So I did the classic StreamBuilder sample to show some list on Flutter:
StreamBuilder<QuerySnapshot>(
stream: getCars()
If the getCars() function is like this, everything is ok:
getCars() {
return Firestore.instance
.collection("users")
.document("oT646MvXXXXXXXXXXXjlN8L1V2")
.collection("cars").snapshots();
}
Let's say that "oT646MvXXXXXXXXXXXjlN8L1V2" is the FirebaseUser uid.
But how can I read FirebaseUser uid dinamically to return the collection?
I tried this code but it didn't work, since it returns a Future:
getCarsError() async {
FirebaseUser fUser = await FirebaseAuth.instance.currentUser();
return Firestore.instance
.collection("users")
.document(fUser.uid)
.collection("cars").snapshots();
}
How can I acompplish that?
thank you
Okay, the idea is to create a stream (I use the rxDart library but you can make it without)
BehaviorSubject<Car> _carController = BehaviorSubject<Car>();
Function(Car) get pushCar => _carController.sink.add;
Stream<Car> get streamCar => _carController ;
...
StreamBuilder<Car>(
stream: streamCar
Then in your async function:
void getCars() async{
FirebaseUser fUser = await FirebaseAuth.instance.currentUser();
Firestore.instance
.collection("users")
.document(fUser.uid)
.collection("cars").getDocuments().then((querySnapshot){
for (document in querySnapshot.documents){
pushCar(Car.fromJson(document.data)); //Deserialize your car here
}).catchError((e)=>print(e)); //Do what you want to handle error
}
So you push asynchronously your car into your stream, and you just get the stream<Car>and print what you have to :)
Hope it's help !!

Resources