Flutter & Firebase

December 20, 2019 Flutter 3 minutes, 36 secondes

Développement Flutter avec Firebase & Clud Firestore

Firebase Auth

Créer un utilisateur

  /// Créer un joueur dans Firebase
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  createUser() async {
    String name = setName();
    String email = 'monemail@bzh-design.com';

    UserModel user = new UserModel(email: email, name: name);
    Firestore.instance.runTransaction((Transaction transaction) async {
      DocumentSnapshot ds = await transaction.get(collection.document());

      user.id = ds.documentID.toString();

      await transaction.set(ds.reference, user.toMap());
      this.fetchUser(user.id);

      SharedPreferencesHelper.setUser(user.id);
    });
  }

Récupérer les données utilisateurs

  /// Chargement du profile de l'utilisateur connecté
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  fetchUser(String userid) async {
    try {
      Firestore.instance
          .collection('users')
          .where("id", isEqualTo: userid)
          .snapshots()
          .listen((data) => data.documents.forEach((doc) {
                UserModel user = docToModel(doc);
                userId = user.id;
                _objFetcher.sink.add(user);
              }));
    } catch (e) {
      print('ERR UserBloc.fetchUser - ' + e.toString());
      throw ('ERR UserBloc.fetchUser - ' + e.toString());
    }
  }

  /// Convertion de l'objet UserModel
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
    UserModel docToModel(DocumentSnapshot doc) {
    UserModel user = new UserModel();

    try {
      user.id = doc["id"];
      user.email = doc["email"];
      user.name = doc["name"];
    } catch (e) {
      print(e.toString());
    }

    return user;
  }

Signin & Signout


final GoogleSignIn _googleSignIn = GoogleSignIn();

final FirebaseAuth _auth = FirebaseAuth.instance;
final CollectionReference collection = Firestore.instance.collection('users');

  /// Connexion basique : email + mdp
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  Future<String> signIn(String email, String password) async {
    AuthResult user;
    try {
      user = await _auth.signInWithEmailAndPassword(
          email: email.trim(), password: password.trim());
    } catch (e) {
      print('ERR signin - ' + e.toString());
    } finally {
      _setUserInPref(user);
    }
    return user != null ? user.user.email : '';
  }

  /// signout
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  signout() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.clear();

    _auth.signOut();
  }

  /// Connexion via le compte Google
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  Future<String> signInGoogle() 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 AuthResult res = await _auth.signInWithCredential(credential);

    return res.user.email;
  }

Cloud Firestore

Gestion d'un CRUD pour des données stockées dans une base de données Firestore. Le code exemple est basé sur l'utilisation du pattern BLOC.


import 'dart:async';
import 'package:rxdart/rxdart.dart';
import '../models/course.model.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:shared_preferences/shared_preferences.dart';

final CollectionReference collection = Firestore.instance.collection('courses');

class CoursesBloc {
  final _objFetcher = PublishSubject<List<CourseModel>>();

  Observable<List<CourseModel>> get courses => _objFetcher.stream;

  final _cFetcher = PublishSubject<CourseModel>();

  Observable<CourseModel> get course => _cFetcher.stream;

  /// Chargement de la liste
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  fetchCourses() async {
    try {
      collection.snapshots().listen((data) {
        List<CourseModel> list = new List<CourseModel>();
        data.documents.forEach((doc) {
          list.add(docToModel(doc));
        });
        _objFetcher.sink.add(list);
      });
    } catch (e) {
      print('ERR CoursesBloc.fetchCourses - ' + e.toString());
      throw ('ERR CoursesBloc.fetchCourses - ' + e.toString());
    }
  }

  /// Conversion d'un objet Firestore
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  CourseModel docToModel(DocumentSnapshot doc) {
    CourseModel course = new CourseModel();

    try {
      course.id = doc['id'];
      course.name = doc['name'];
      course.nbholes = doc['nbholes'];
      course.par = doc['par'];
      course.holes = doc['holes'];
    } catch (e) {
      print(e.toString());
    }

    return course;
  }

  /// Suppression d'un objet
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  Future<dynamic> deleteCourse(String id) async {
    final TransactionHandler deleteTransaction = (Transaction tx) async {
      final DocumentSnapshot ds = await tx.get(collection.document(id));

      await tx.delete(ds.reference);
      return {'deleted': true};
    };

    return Firestore.instance
        .runTransaction(deleteTransaction)
        .then((result) => result['deleted'])
        .catchError((error) {
      print('error: $error');
      return false;
    });
  }

  /// Mise à jour d'un objet
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  Future<dynamic> updateCourse(CourseModel course) async {
    final TransactionHandler updateTransaction = (Transaction tx) async {
      final DocumentSnapshot ds = await tx.get(collection.document(course.id));
      await tx.update(ds.reference, course.toMap());
      return {'updated': true};
    };

    return Firestore.instance
        .runTransaction(updateTransaction)
        .then((result) => result['updated'])
        .catchError((error) {
      print('error: $error');
      return false;
    });
  }

  /// Création d'un objet
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  createCourse(CourseModel course) async {
    Firestore.instance.runTransaction((Transaction transaction) async {
      DocumentSnapshot ds = await transaction.get(collection.document());
      await transaction.set(ds.reference, course.toMap());
    });
  }

  /// Récupération d'un objet basé sur un id
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws Exception
  fetchCourse(String id) async {
    try {
          collection
          .where("id", isEqualTo: id)
          .snapshots()
          .listen((data) => data.documents.forEach((doc) {
                CourseModel course = docToModel(doc);
                course.holeList = courseHoleListFromJson(course.holes);

                _cFetcher.sink.add(course);
              }));
    } catch (e) {
      print('ERR CoursesBloc.fetchCourse - ' + e.toString());
      throw ('ERR CoursesBloc.fetchCourse - ' + e.toString());
    }
  }

  /// Fonction Dispose
  ///
  /// @param NONE
  /// @returns NONE
  /// @throws NONE
  dispose() {
    _objFetcher.close();
    _cFetcher.close();
  }
}

/// Singleton pour utiliser le bloc
final coursesbloc = CoursesBloc();

alt