Writing data to Firebase: Adding the favorite feature

We want to give users the ability to choose their favorite parts of the event program. In this way, we'll also see how to write data to the Cloud Firestore database, and to query data based on specific selection criteria.

Just as we did for the EventDetail class, let's create a new model class that will contain the user's favorites, as follows:

  1. Let's create a new file in the models directory, called favorite.dart.
  1. A favorite object needs to contain an ID, the user ID (UID) of the user, and the ID of the selected event detail. We'll mark all the properties as private, and we'll create an unnamed constructor to set a new instance of a favorite, as follows:
class Favorite {
String _id;
String _eventId;
String _userId;
Favourite(this._id, this._eventId, this._userId);
}
  1. Then, we'll create a named constructor called map that will take a DocumentSnapshot containing data read from a document in a Cloud Firestore database. In a DocumentSnapshot object, you always find a documentId, which is the ID of the document, and a data object, which contains the key-value pairs that were specified inside the document, as shown in the following code snippet:
  Favourite.map(DocumentSnapshot document) {
this._id = document.documentID;
this._eventId = document.data['eventId'];
this._userId = document.data['userId'];
}
  1. We also need to create a method that returns a Map, so that it will be easier to write data to the Cloud Firestore database. We can call this method toMap(). The keys of the Map will be Strings, and its values will be dynamic. The code of the toMap() method is shown in the following code snippet:
  Map<String, dynamic> toMap() {
Map map = Map<String, dynamic>();
if (_id!= null) {
map['id'] = _id;
}
map['eventId'] = _eventId;
map['userId'] = _userId;
return map;
}

The Favourite class is now complete. What we need now is to build the methods that will perform the required reading and writing tasks. As there will be several methods, and it's always a good idea to separate the logic of an app from the UI, we'll create a new file to host those methods, as follows:

  1. In the shared folder, create a new file called firestore_helper.dart. This will contain helper methods to interact with the Cloud Firestore database.
  1. In this file, import the two model classes and the Cloud Firestore package.
  2. Then, create a static db property, which will be an instance of Firestore and will be used throughout the class, as shown in the following code snippet:
import '../models/event_detail.dart';
import '../models/favourite.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class FirestoreHelper {
static final Firestore db = Firestore.instance;
}

All methods of this class will be static, as we don't actually need to instantiate this class in order to use them.

  1. The first method we'll create in this class will add a new favorite into the Firestore database. It's a static method called addFavourite that will take the currently logged-in user uid, and the Event that will be added as a favorite, as follows:
  static Future addFavourite(EventDetail eventDetail, String uid) {
Favourite fav = Favourite(null, uid, eventDetail.id);
var result = db.collection('favourites').add(fav.toMap())
.then((value) => print(value))
.catchError((error)=> print (error));
return result;
}

As you can see, inside the method, we create an instance of the Favourite class and call it fav. Then, from the database instance, we add to the collection called favourites the fav object, transformed into a Map.

We print the result in the Debug console if everything works correctly, or print the error if something goes wrong.

Now, we need a way to enable the user to add their favorites from the UI. To make this possible, we can add a star icon in the event calendar list so that, when the user presses the star icon, the favorite will be added. Later on, we'll also change the icon color, so that the favorites will be immediately recognizable.

Before we add the star IconButton, after logging in, let's send to the event screen the UID of the user that was logged in. In this way, it will be easier to read and write the favorites data from the screen itself.

We will proceed as follows:

  1. In the EventScreen class, let's add a String uid property and set it in the constructor, as follows:
final String uid;
  1. When we call the EventList class from the body of the Scaffold, let’s pass the uid, like this:
EventList(uid);
  1. We'll do the same in the EventList class, adding a uid property and receiving it in the constructor, as follows:
final String uid;
EventList(this.uid);
  1. In this way, we've propagated the uid from the authentication process back to the _EventListState, and now we have all the data we need to read and write the user's favorites.
  1. Now, let's create a method called toggleFavourite() that will take the EventDetail that has to become a favorite and call the FirestoreHelper addFavourite() method, as follows:
void toggleFavourite(EventDetail ed) {
FirestoreHelper.addFavourite(ed, widget.uid);
}
  1. Then, in the build() method of the EventListState class in the event_screen.dart file, let's add a trailing IconButton widget to the ListTile in the ListViewBuilder widget. This will be the widget that will add the favorites from the Cloud Firestore database; later, we'll also use colors to tell the user whether the current item on a list is a favorite or not and whether to remove the favorite from the database. The code for this is illustrated in the following snippet: 
trailing: IconButton(
icon: Icon(Icons.star, color: Colors.grey),
onPressed: () {toggleFavourite(details[position]);},
),
  1. Before trying this new feature, we need to modify the calls to the EventScreen class. One is in the LaunchScreenState class, in the launchscreen.dart file. When we set the route that calls the EventScreen class, we need to modify the route, as shown in the following snippet:
route = MaterialPageRoute(builder: (context) => EventScreen(user.uid));
  1. Then, in the login_screen.dart file, in the submit() method of the _LoginScreenState class, we need to add the _userId variable to the MaterialPageRoute, as shown in the following snippet:
if (_userId != null) {
Navigator.push(
context, MaterialPageRoute(builder: (context)=>
EventScreen(_userId))
);
}
  1. Let's try the app now. In the events screen, press the star IconButton on any item of the List. If everything is working correctly, when you go to your Firebase console and see the database data, you should find a Favorites collection with some data in it, as shown in the following screenshot:

This means that the app is now writing favorites to the Cloud Firestore database.

Next, we need to read the favorites, give some feedback to the user, and delete the favorites from the database.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.121.8