Karol Rarun
Karol Rarun

Reputation: 23

Flutter : Save user id from firestore using Shared Preferences and retrieve the value into class

So first of all I'm new in Flutter. I want to use current sign in user id from firebase as filter from data that i want to show in apps.Please Help Me.

here is the user id from wrapper.dart I want to use.

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final User user = Provider.of<User>(context);
    print(user.uid);

and here i want to pass the value as uid from database.dart

Stream<List<InitialRPP>> get dataInitRPP {
    return dbRPP
        .where('uid', isEqualTo: uid)
        .snapshots()
        .map(_initRPPFromSnapshot);
  }

Here is the full source code

wrapper.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rppapps/models/user.dart';
import 'package:rppapps/screens/authenticate/authenticate.dart';
import 'package:rppapps/screens/home/home.dart';

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final User user = Provider.of<User>(context);
    print(user.uid);

    // Login or Home
    if (user == null) {
      return Authenticate();
    } else {
      return Home();
    }
  }
}

database.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:rppapps/models/model.dart';

class DatabaseService {

  // the code should be in here "String uid;" like that

  //collection reference
  final CollectionReference dbRPP = Firestore.instance.collection('rpp');

  Future addinitialRPP(String uid, String nama, String tahun, String kelas,
      String semester, String mapel, String materi) async {
    return await dbRPP.add({
      'uid': uid,
      'nama': nama,
      'tahun': tahun,
      'kelas': kelas,
      'semester': semester,
      'mapel': mapel,
      'materi': materi
    });
  }

  List<InitialRPP> _initRPPFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.documents.map((doc) {
      return InitialRPP(
          uid: doc.data['uid'] ?? '',
          nama: doc.data['nama'] ?? '',
          tahun: doc.data['tahun'] ?? '',
          kelas: doc.data['kelas'] ?? '',
          semester: doc.data['semester'] ?? '',
          mapel: doc.data['mapel'] ?? '',
          materi: doc.data['materi'] ?? '');
    }).toList();
  }

  Stream<List<InitialRPP>> get dataInitRPP {
    return dbRPP
        .where('uid', isEqualTo: uid)
        .snapshots()
        .map(_initRPPFromSnapshot);
  }
}

EDIT: (sign in sign out method and firebase_auth)

auth.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:rppapps/models/user.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // created user object based on FirebaseUser
  User _userFromFirebaseUser(FirebaseUser user) {
    return user != null ? User(uid: user.uid) : null;
  }

  // auth change user stream
  Stream<User> get user {
    return _auth.onAuthStateChanged.map(_userFromFirebaseUser);
  }

  // sign anon
  Future signInAnon() async {
    try {
      AuthResult result = await _auth.signInAnonymously();
      FirebaseUser user = result.user;
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  // sign with email and pass
  Future signInWithEmailAndPassword(String email, String password) async {
    try {
      AuthResult result = await _auth.signInWithEmailAndPassword(
          email: email, password: password);
      FirebaseUser user = result.user;
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  // register with email and pass
  Future registerWithEmailAndPassword(String email, String password) async {
    try {
      AuthResult result = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);
      FirebaseUser user = result.user;
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  // sign out
  Future signOut() async {
    try {
      return await _auth.signOut();
    } catch (e) {
      print(e.toString());
      return null;
    }
  }
}

pubspec.yaml

  firebase_auth: ^0.14.0+5
  cloud_firestore: ^0.12.9+4
  provider: ^3.1.0

Upvotes: 0

Views: 1544

Answers (1)

LucasACH
LucasACH

Reputation: 169

Try using onAuthStateChanged() instead. You can check if the user is logged in by adding this Stream to a Streambuilder. Any time the user logs out or in, the Stream automatically updates. Then wrap your Home widgets with a FutureBuilder and pass the currentUser() future. This will return a snapshot containing the user information, such as email and uid.

Finally, you can filter widgets by checking if the uid is the same as the given one. For example, if a user is admin or not.

enter image description here

wrapper.dart

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder<FirebaseUser>(
        stream: AuthService().authStateChanges(),
        builder: (context, AsyncSnapshot snapshot) {

          // if the stream has data, the user is logged in
          if (snapshot.hasData) {

            // isLoggedIn
            return Home();

          } else if (snapshot.hasData == false &&
          snapshot.connectionState == ConnectionState.active) {

            // isLoggedOut
            return Authenticate();

          } else {
            return CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

auth.dart

class AuthService {
  final FirebaseAuth _firebaseInstance = FirebaseAuth.instance;
  final CollectionReference _usersCollection =
      Firestore.instance.collection("users");

  // User State
  Stream<FirebaseUser> authStateChanges() {
    FirebaseAuth _firebaseInstance = FirebaseAuth.instance;
    return _firebaseInstance.onAuthStateChanged;
  }

  // Current User
  Future<FirebaseUser> currentUser() async {
    FirebaseAuth _firebaseInstance = FirebaseAuth.instance;
    return _firebaseInstance.currentUser();
  }

  // Sign Out
  Future<void> signOut() async {
    FirebaseAuth _firebaseInstance = FirebaseAuth.instance;
    return _firebaseInstance.signOut();
  }

  // Sign In Anonymously
  Future<AuthResult> signInAnon() async {
    return await _firebaseInstance.signInAnonymously().catchError((error) {
      print(error);
    });
  }

  // Sign In With Email And Password
  Future<AuthResult> signIn(String email, String password) async {
    return await _firebaseInstance
        .signInWithEmailAndPassword(email: email, password: password)
        .catchError((error) {
      switch (error.code) {
        case "ERROR_INVALID_EMAIL":
          print("ERROR_INVALID_EMAIL");
          break;
        case "ERROR_WRONG_PASSWORD":
          print("ERROR_WRONG_PASSWORD");
          break;
        case "ERROR_USER_NOT_FOUND":
          print("ERROR_USER_NOT_FOUND");
          break;
        case "ERROR_USER_DISABLED":
          print("ERROR_USER_DISABLED");
          break;
        case "ERROR_TOO_MANY_REQUESTS":
          print("ERROR_TOO_MANY_REQUESTS");
          break;
        case "ERROR_NETWORK_REQUEST_FAILED":
          print("ERROR_NETWORK_REQUEST_FAILED");
          break;
      }
    });
  }

  // Create User With Email And Password
  Future<AuthResult> signUp(String email, String password) async {
    return await _firebaseInstance
        .createUserWithEmailAndPassword(email: email, password: password)
        .catchError(
      (error) {
        switch (error.code) {
          case "ERROR_INVALID_EMAIL":
            print("ERROR_INVALID_EMAIL");
            break;
          case "ERROR_WEAK_PASSWORD":
            print("ERROR_WEAK_PASSWORD");
            break;
          case "ERROR_EMAIL_ALREADY_IN_USE":
            print("ERROR_EMAIL_ALREADY_IN_USE");
            break;
          case "ERROR_NETWORK_REQUEST_FAILED":
            print("ERROR_NETWORK_REQUEST_FAILED");
            break;
        }
      },
    ).then((user) {
      if (user != null) {
        _usersCollection.document(user.user.uid).setData(
          {
            "email": user.user.email,
            "uid": user.user.uid,
          },
        );
        return null;
      } else {
        return null;
      }
    });
  }
}

authenticate.dart

class Authenticate extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Center(child: Text("Authenticate")),

        // Sign In Button
        RaisedButton(
          onPressed: () => AuthService().signIn("[email protected]", "password"),
          child: Text("Sign In as user 01"),
        ),
        RaisedButton(
          onPressed: () => AuthService().signIn("[email protected]", "password"),
          child: Text("Sign In as user 02"),
        )
      ],
    );
  }
}

home.dart

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<FirebaseUser>(
      future: AuthService().currentUser(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          String userEmail = snapshot.data.email;
          String userUid = snapshot.data.uid;

          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Center(child: Text("Home")),

              // Get Current User Email
              Center(child: Text(userEmail)),

              // Get Current User UID
              Center(child: Text(userUid)),

              // Filter By UID
              Builder(
                builder: (context) {
                  if (userUid == "X6Ibch8OwmZWrYIB1F3IPpbBQbk2") {
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.admin_panel_settings),
                        Text("Admin"),
                      ],
                    );
                  }
                  return Container();
                },
              ),

              // Sign Out Button
              RaisedButton(
                onPressed: () => AuthService().signOut(),
                child: Text("Sign Out"),
              )
            ],
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }
}

Upvotes: 2

Related Questions