Flutter Facebook Login Error: Getter not found: 'Success'. case FacebookLoginStatus.Success - flutter

I am using Flutter to make my app and I wish to do function login with Facebook and this is what I did:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_login_facebook/flutter_login_facebook.dart';
abstract class AuthBase {
User get currentUser;
Stream<User> authStateChanges();
Future<User> signInWithFacebook();
Future<void> signOut();
}
class Auth implements AuthBase {
final _firebaseAuth = FirebaseAuth.instance;
#override
Stream<User> authStateChanges() => _firebaseAuth.authStateChanges();
#override
User get currentUser => _firebaseAuth.currentUser;
#override
Future<User> signInWithFacebook() async {
final fb = FacebookLogin();
final response = await fb.logIn(permissions: [
FacebookPermission.publicProfile,
FacebookPermission.email,
]);
switch (response.status) {
case FacebookLoginStatus.Success:
final accessToken = response.accessToken;
final userCredential = await _firebaseAuth.signInWithCredential(
FacebookAuthProvider.credential(accessToken.token),
);
return userCredential.user;
case FacebookLoginStatus.Cancel:
throw FirebaseAuthException(
code: 'ERROR_ABORTED_BY_USER',
message: 'Sign in aborted by user',
);
case FacebookLoginStatus.Error:
throw FirebaseAuthException(
code: 'ERROR_FACEBOOK_LOGIN_FAILED',
message: response.error.developerMessage,
);
default:
throw UnimplementedError();
}
}
#override
Future<void> signOut() async {
final facebookLogin = FacebookLogin();
await facebookLogin.logOut();
await _firebaseAuth.signOut();
}
}
And this is error I got:
Performing hot restart...
Syncing files to device AOSP on IA Emulator...
lib/services/auth.dart:68:32: Error: Getter not found: 'Success'.
case FacebookLoginStatus.Success:
^^^^^^^
lib/services/auth.dart:74:32: Error: Getter not found: 'Cancel'.
case FacebookLoginStatus.Cancel:
^^^^^^
lib/services/auth.dart:79:32: Error: Getter not found: 'Error'.
case FacebookLoginStatus.Error:
^^^^^
Restarted application in 278ms.
I tried to look at the tutorial and I see no difference in the code I wrote, it is on Udemy so I can not copy the link down here to you. Please tell me how to deal with that, thank you so much and have a good day

change code to
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_login_facebook/flutter_login_facebook.dart';
abstract class AuthBase {
User get currentUser;
Stream<User> authStateChanges();
Future<User> signInWithFacebook();
Future<void> signOut();
}
class Auth implements AuthBase {
final _firebaseAuth = FirebaseAuth.instance;
#override
Stream<User> authStateChanges() => _firebaseAuth.authStateChanges();
#override
User get currentUser => _firebaseAuth.currentUser;
#override
Future<User> signInWithFacebook() async {
final fb = FacebookLogin();
final response = await fb.logIn(permissions: [
FacebookPermission.publicProfile,
FacebookPermission.email,
]);
switch (response.status) {
case FacebookLoginStatus.success:
final accessToken = response.accessToken;
final userCredential = await _firebaseAuth.signInWithCredential(
FacebookAuthProvider.credential(accessToken.token),
);
return userCredential.user;
case FacebookLoginStatus.cancel:
throw FirebaseAuthException(
code: 'ERROR_ABORTED_BY_USER',
message: 'Sign in aborted by user',
);
case FacebookLoginStatus.error:
throw FirebaseAuthException(
code: 'ERROR_FACEBOOK_LOGIN_FAILED',
message: response.error.developerMessage,
);
default:
throw UnimplementedError();
}
}
#override
Future<void> signOut() async {
final facebookLogin = FacebookLogin();
await facebookLogin.logOut();
await _firebaseAuth.signOut();
}
}
lower case this code:
case FacebookLoginStatus.Success: to case FacebookLoginStatus.success:
case FacebookLoginStatus.Cancel: to case FacebookLoginStatus.cancel:
case FacebookLoginStatus.Error: to case FacebookLoginStatus.error:

Please try this snippet of code, It's working fine for me.
fbSignIn() async {
var facebookLogin = FacebookLogin();
var facebookLoginResult = await facebookLogin.logIn(['email']);
switch (facebookLoginResult.status) {
case FacebookLoginStatus.error:
print("Error");
//showToast(msg: "A Error Occured");
break;
case FacebookLoginStatus.cancelledByUser:
print("CancelledByUser");
//showToast(msg: "Login Cancelled");
break;
case FacebookLoginStatus.loggedIn:
print(facebookLoginResult.accessToken.token);
print("LoggedIn");
break;
}
}

Related

Flutter: LateError (LateInitializationError: Field 'user' has not been initialized.)

I am nit sure about this error because user should be inithialized in Auth Provider and then I will be able to use it in User Provider but flutter continue giving this error.
Here is my code. Can someone help to solve or tell me a better form to organize it?
AuthProvider
class AuthProvider extends ChangeNotifier {
late final FirebaseAuth _auth;
late final NavigationService _navigationService;
late final DatabaseService _databaseService;
late UserData user;
AuthProvider() {
_auth = FirebaseAuth.instance;
_navigationService = GetIt.instance.get<NavigationService>();
_databaseService = GetIt.instance<DatabaseService>();
_auth.authStateChanges().listen((_user) {
if (_user != null) {
//_databaseService.updateUserLastSeenTime(_user.uid);
_databaseService.getUser(_user.uid).then(
(_snapshot) {
if (_snapshot.exists) {
if (_snapshot.data() != null) {
user =
UserData.fromJson(jsonDecode(jsonEncode(_snapshot.data())));
notifyListeners();
}
}
_navigationService.removeAndNavigateToRoute('/home');
},
);
} else {
_navigationService.removeAndNavigateToRoute('/login');
}
});
}
User Provider
class UserProvider with ChangeNotifier {
final DatabaseService _databaseService = DatabaseService();
UserData _user = AuthProvider().user;
UserData get getUser => _user;
Future<void> refreshUser() async {
UserData user = await _databaseService.getUserDetails();
_user = user;
notifyListeners();
}
// update user name
Future<void> editName(String name) async {
try {
await _databaseService.getUserDoc(_user.uid).update({'name': name});
} catch (err) {
print(err.toString());
}
}
// update user last name
Future<void> editLastName(String lastName) async {
try {
await _databaseService
.getUserDoc(_user.uid)
.update({'lastName': lastName});
} catch (err) {
print(err.toString());
}
}
}

Flutter FirebaseAuth unit testing

I'm trying to test my whole AuthManager class which use FirebaseAuth to signin, login. Here my file:
class AuthManager extends ChangeNotifier {
final FirebaseAuth auth;
Stream<User?> get user => auth.authStateChanges();
static Future<FirebaseApp> initializeFirebase({
required BuildContext context,
}) async {
FirebaseApp firebaseApp = await Firebase.initializeApp();
return firebaseApp;
}
AuthManager({required this.auth});
Future<String> signup(String email, String password) async {
try {
final credential = await auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
return "Success";
} on FirebaseAuthException catch (e) {
rethrow;
}
}
Future<String> signInWithEmailAndPassword(
String email, String password) async {
try {
final userCredential = await auth.signInWithEmailAndPassword(
email: email, password: password);
return "Success";
} on FirebaseAuthException catch (e) {
return "Failed";
} catch (e) {
rethrow;
}
}
static Future<String> signOut() async {
try {
await FirebaseAuth.instance.signOut();
return "Success";
} catch (e) {
rethrow;
}
}
}
I used to return the usercredential but wanted to try test a simple string return for the test, following this tutorial: https://www.youtube.com/watch?v=4d6hEaUVvuU, here is my test file
import 'package:firebase_auth/firebase_auth.dart';
import 'package:notes_firebase_app/data/models/auth_manager.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
class MockFirebaseAuth extends Mock implements FirebaseAuth {
#override
Stream<User> authStateChanges() {
return Stream.fromIterable([
_mockUser,
]);
}
}
class MockUser extends Mock implements User {}
final MockUser _mockUser = MockUser();
class MockUserCredential extends Mock implements Future<UserCredential> {}
void main() {
final MockFirebaseAuth mockFirebaseAuth = MockFirebaseAuth();
final AuthManager authManager = AuthManager(auth: mockFirebaseAuth);
final MockUserCredential mockUserCredential = MockUserCredential();
setUp(() {});
test("emit occurs", () async {
expectLater(authManager.user, emitsInOrder([_mockUser]));
});
test("create account", () async {
when(mockFirebaseAuth.createUserWithEmailAndPassword(
email: "tadas#gmail.com", password: "123456"))
.thenAnswer((realInvocation) => null);
expect(
await authManager.signInWithEmailAndPassword(
"tadas#gmail.com", "123456"),
"Success");
});
}
I face two problems here, cannot pass null because we need to handle it now or this throw this error
The return type 'Null' isn't a 'Future<UserCredential>', as required by the closure's context
Then I tried to mock UserCredential like this.
final MockUserCredential mockUserCredential = MockUserCredential();
when(mockFirebaseAuth.createUserWithEmailAndPassword(
email: "tadas#gmail.com", password: "123456"))
.thenAnswer((realInvocation) => mockUserCredential);
but I'm getting this error:
type 'Null' is not a subtype of type 'Future<UserCredential>'
What am I doing wrong ? Help will be much appreciated.
I am not totally sure but mockito package may need a generator. Try mocktail package and use
when(()=> mockFirebaseAuth.createUserWithEmailAndPassword(
email: "tadas#gmail.com", password: "123456")).thenAnswer((realInvocation) => null);
use callback function in when().

I'm trying to implementation Facebook SDK using Firebase but I keep getting an error on the when I copy this code in the correct spot

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
dependencies {
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:29.0.1')
// Add the dependency for the Firebase SDK for Google Analytics
// When using the BoM, don't specify versions in Firebase dependencies
implementation 'com.google.firebase:firebase-analytics'
// Add the dependencies for any other desired Firebase products
// https://firebase.google.com/docs/android/setup#available-libraries
implementation 'com.facebook.android:facebook-android-sdk:latest.release'
}
}
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
abstract class AuthBase{
User get currentUser;
Stream<User> authStateChanges();
Future<User>signInAnonymously();
Future<User> signInWithGoogle();
Future<void>signOut();
}
class Auth implements AuthBase {
final _firebaseAuth = FirebaseAuth.instance;
Stream<User> authStateChanges() => _firebaseAuth.authStateChanges();
#override
User get currentUser => _firebaseAuth.currentUser;
#override
Future<User> signInAnonymously() async {
final userCredential = await _firebaseAuth.signInAnonymously();
return userCredential.user;
}
#override
Future<User> signInWithGoogle() async{
final googleSignIn = GoogleSignIn();
final googleUser = await googleSignIn.signIn();
if(googleUser !=null) {
final googleAuth = await googleUser.authentication;
if (googleAuth.idToken != null) {
final userCredential = await _firebaseAuth.signInWithCredential(
GoogleAuthProvider.credential(
idToken: googleAuth.idToken,
accessToken: googleAuth.accessToken,
));
return userCredential.user;
} else {
throw FirebaseAuthException(
code:'ERROR_MISSING_GOOGLE_ID_TOKEN',
message:'Missing Google ID Token',
);
}
}
else {
throw FirebaseAuthException(
code: 'ERROR_ABORTED_BY_USER',
message: 'Sign in aborted by user'
);
}
}
Future<User> signInWithFacebook() async{
final fb = FacebookLogin();
}
#override
Future<void> signOut() async {
final googleSignIn = GoogleSignIn();
await googleSignIn.signOut();
await _firebaseAuth.signOut();
// TODO: implement signOut
throw UnimplementedError();
}
}
`]1][1][I'm trying to implement facebook SDK into my project.I have followed all of the steps up to this point and you can find the link below but I'm still getting an error When I copied this code in to the Main activity page.What am I doing wrong?I posted my auth.dart file and the dependencies as well
package com.example.time_trackerpractice
import io.flutter.embedding.android.FlutterActivity
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
class MainActivity: FlutterActivity() {
}
The problem that you have (see image) its because you don't have any flutter packages related to facebook auth.
In this line of your code you are try instance a FacebookLogin, but doesn't exits any import related to facebook login.
final fb = FacebookLogin();
You can use this package to facebook login (flutter_facebook_auth), and replace your inside code of your function signInWithFacebook for this:
Future<User> signInWithFacebook() async {
final result = await FacebookAuth.instance
.login(permissions: ['email', 'public_profile']);
final accessToken = result.accessToken;
final credential = FacebookAuthProvider.credential(accessToken.token);
userCredential = await _firebaseAuth.signInWithCredential(credential);
return userCredential.user
}

why Flutter login with facebook is not working

I'm trying to make a login screen with Facebook but end up with this error when I run my code. here is my code:
import 'package:facebook_login/services/auth_service.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_login_facebook/flutter_login_facebook.dart';
import 'package:auth/auth.dart';
class AuthBloc {
final authService = AuthService();
final fb = FacebookLogin();
Stream<User> get currentUser => authService.currentUser;
loginFacebook() async {
print('Starting Facebook Login');
final res = await fb.logIn(
permissions: [
FacebookPermission.publicProfile,
FacebookPermission.email
]
);
switch(res.status){
case FacebookLoginStatus.Success:
print('It worked');
//Get Token
final FacebookAccessToken fbToken = res.accessToken;
//Convert to Auth Credential
final AuthCredential credential
= FacebookAuthProvider.getCredential(accessToken: fbToken.token);
//User Credential to Sign in with Firebase
final result = await authService.signInWithCredentail(credential);
print('${result.user.displayName} is now logged in');
break;
case FacebookLoginStatus.Cancel:
print('The user canceled the login');
break;
case FacebookLoginStatus.Error:
print('There was an error');
break;
}
}
logout(){
authService.logout();
}
}
when i run this i get this error message
Invalid depfile: C:\Users\Main\OneDrive\stuff\Documents\seltech\st\.dart_tool\flutter_build\7b28b646cfa2e7424746c78d0801893a\kernel_snapshot.d
Error: Couldn't resolve the package 'facebook_login' in 'package:facebook_login/services/auth_service.dart'.
Error: Couldn't resolve the package 'auth' in 'package:auth/auth.dart'.
lib/src/bloc/auth_bloc:1:8: Error: Not found: 'package:facebook_login/services/auth_service.dart'
import 'package:facebook_login/services/auth_service.dart';
there are more errors that pop up.
if you need more of the code I can send some more of it
it's so much it won't fit in here
all of the error I get is from the auth_block. I have another login page made on a separate screen.
I also have a manual login with firebase auth there .
With these packages on the pubspec:
flutter_facebook_auth: ^3.5.1
firebase_auth: ^3.1.0
firebase_core: ^1.6.0
And this function:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
final FirebaseAuth _auth = FirebaseAuth.instance;
Future<String?> facebookSignin() async {
try {
final _instance = FacebookAuth.instance;
final result = await _instance.login(permissions: ['email']);
if (result.status == LoginStatus.success) {
final OAuthCredential credential =
FacebookAuthProvider.credential(result.accessToken!.token);
final a = await _auth.signInWithCredential(credential);
await _instance.getUserData().then((userData) async {
await _auth.currentUser!.updateEmail(userData['email']);
});
return null;
} else if (result.status == LoginStatus.cancelled) {
return 'Login cancelled';
} else {
return 'Error';
}
} catch (e) {
return e.toString();
}
}
I'm able to login with facebook on my app
don't forget to also follow the configuration steps for android/ios and facebook for developers console
enter image description here
#enable this Permissions and features
then it will work

How do i use StateNotifier riverpod to track the changes of enum value

I'm trying to use Riverpod stateNotifier to track the changes of an enum during user authentication to determine the appropriate screen to be displayed. Eg SignUp, SignIn, Homepage or the Authenticating screen but I get this error back in my named constructor:
The superclass 'StateNotifier' doesn't have a zero argument constructor.
Try declaring a zero argument constructor in 'StateNotifier', or explicitly invoking a different constructor in 'StateNotifier'.
I know that there something i don't understand here but i can't figure it out.
Here is my code:
enum Status {
unInitialized,
unauthenticated,
authenticating,
authenticated,
processing
}
class AuthWithEmailPassword extends StateNotifier<Status> {
AuthWithEmailPassword() : super(Status.authenticated);
Status _status = Status.authenticated;
// AuthWithEmailPassword();
UserServices _userServices = UserServices();
FirebaseAuth _auth;
UserModel _userModel;
User _user;
Status get status => _status;
User get user => _user;
UserModel get userModel => _userModel;
//Name consturctor of this class
#override
AuthWithEmailPassword.initialize()
: _auth = FirebaseAuth.instance{
_status = Status.unInitialized;
_auth.authStateChanges().listen((User value) async {
_status = Status.unInitialized;
if (value == null) {
_status = Status.unauthenticated;
print('user is signed out');
} else {
_userModel = await _userServices.getUserByUid(id: value.uid);
_status = Status.authenticated;
_user = value;
print('user signed in');
}
});
}}
Instead of using a named constructor, you could create an initialize function and call it in your StateNotifierProvider.
For example:
class AuthWithEmailPassword extends StateNotifier<Status> {
AuthWithEmailPassword() : super(Status.authenticated);
Status _status = Status.authenticated;
Status get status => _status;
final FirebaseAuth _auth = FirebaseAuth.instance;
User _user;
User get user => _user;
UserModel _userModel;
UserModel get userModel => _userModel;
bool _init = false;
late StreamSubscription _sub;
void initialize() {
if (_init) return;
_status = Status.unInitialized;
_sub = _auth.authStateChanges().listen(_listener);
_init = true;
}
#override
void dispose() {
_sub.cancel();
super.dispose();
}
Future<void> _listener(User? value) async {
_status = Status.unInitialized;
if (value == null) {
_status = Status.unauthenticated;
print('user is signed out');
} else {
_userModel = await _userServices.getUserByUid(id: value.uid);
_status = Status.authenticated;
_user = value;
print('user signed in');
}
}
}
final authWithEmailPasswordProvider = StateNotifierProvider.autoDispose<AuthWithEmailPassword, Status>((_) {
return AuthWithEmailPassword()..initialize();
});
Thanks to Alex Hartford who helped me with a solution when i was desperate on this issue. I have finally been able to figure out another solution also and maybe someone might like it.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_ecom/controle/userServices.dart';
import 'package:flutter_ecom/models/userModel.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
enum Status {
unInitialized,
unauthenticated,
authenticating,
authenticated,
}
final authStatus = StateNotifierProvider<AuthWithEmailPassword, Status>(
(ref) => AuthWithEmailPassword.initialize());
class AuthWithEmailPassword extends StateNotifier<Status> {
FirebaseFirestore firestore = FirebaseFirestore.instance;
UserServices _userServices = UserServices();
// Status state = Status.unInitialized;
FirebaseAuth _auth;
UserModel _userModel;
User _user;
// Status get status => _status;
User get user => _user;
UserModel get userModel => _userModel;
String _error;
String get error => _error;
//Name consturctor of this class
AuthWithEmailPassword.initialize()
: _auth = FirebaseAuth.instance,
super(Status.unInitialized) {
_auth.authStateChanges().listen((User value) async {
await Future.delayed(
const Duration(milliseconds: 4000),
);
if (value == null) {
state = Status.unauthenticated;
print('user is signed out');
} else {
_userModel = await _userServices.getUserByUid(id: value.uid);
state = Status.authenticated;
_user = value;
print('user signed in');
}
});
}