How to use Windows Authentication (Azure AD) in Flutter with Firebase - firebase

I am currently developing an app which requires windows authentication.
Access should only been given to users known in the azure active directory of the company.
I already:
created an app registration with read access to azure.
activated windows auth in my firebase project
There is some example code available on:
https://firebase.google.com/docs/auth/android/microsoft-oauth?authuser=0
but it is not very well explained where I can get some of the used classes like 'OnSuccessListener' etc.
I would appreciate if someone can provide me some best practice code how to use the windows auth in flutter with firebase or also without firebase. Hopefully there is a possibility without storing the app registration secretly in the code.
In the end I need the usertoken to make api calls.

Without Firebase you have the msal_mobile [1] package that will Authenticate with Azure AD on iOS and Android.
There's step-by-step instructions within the package for setting up within the Azure portal, along with the iOS and Android platforms. Then the Flutter code to sign-in is simply:
await msal.signIn(null, ["api://[app-registration-client-id]/user_impersonation"]).then((result) {
print('access token: ${result.accessToken}');
})
Link
[1]: https://pub.dev/packages/msal_mobile

There is now a way for you to sign in with Microsoft using Firebase Auth but at the time of writing, I haven't seen a way to use it in tandem with MS Graph. For those who don't need graph access, here's the method I used:
Pubspec.yaml
firebase_auth: ^0.18.3
firebase_core: ^0.5.2
Your Widget
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: RaisedButton(
child: Text('login'),
onPressed: () async {
try {
User user =
await FirebaseAuthOAuth().openSignInFlow("microsoft.com", [
"https://graph.microsoft.com/User.Read",
"https://graph.microsoft.com/User.ReadBasic.All"
], {
'tenant': '' //Your tenant ID here
});
print(user);
} on PlatformException catch (error) {
debugPrint("${error.code}: ${error.message}");
}
},
),
),
);
}
}
Assuming you've setup Firebase Auth and Azure App registrations properly, this should be enough for you to sign in via MS

Related

Flutter - Provider working for Web app but when I run on Android it breaks?

I am creating a cross platform flutter app and started developing on the Web version. I have used provider throughout to pass various pieces of data around my app and thus far it works well.
However, when I run my app on Android, the same provider I have used to pull data from Firestore doesn't register any values. When I run on web, I get 2 when I print the length of my list of values whereas on Android, I get 0.
I appreciate there isn't a great deal of information here, but i'm wondering if anyone else has experienced the same issue? And if so, how did you resolve it? Thanks.
UPDATE - added code
Here is how I access the stream from firestore:
class OurDatabase {
final CollectionReference customCollection =
FirebaseFirestore.instance.collection('myCollection');
Stream<List<CustomClass>> get customitems {
return customCollection.snapshots().map(
(QuerySnapshot querySnapshot) => querySnapshot.docs
.map(
(document) => CustomClass.fromFirestore(document),
)
.toList(),
);
}
Here is my main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MultiProvider(
providers: [
StreamProvider<List<CustomClass>>.value(
value: OurDatabase().customitems,
initialData: <CustomClass>[],
),
],
child: MaterialApp(theme: OurTheme().buildTheme(), home: OurHomePage()),
),
);
}
I then access the custom list here:
class OurHeadlineList extends StatelessWidget {
#override
Widget build(BuildContext context) {
final List<CustomClass> items =
Provider.of<List<CustomClass>>(context);
print(items .length);
return Container();
}
}
I have swapped out provider for a stream builder and that works - I guess the problem lies with provider?
Like I mentioned previously, when I run on Chrome, the provider works perfectly. But when I run on Android emulator, it doesn't pick up any of the values. I am able to log into firebase through both platforms which confuses me even more. Thoughts?

Limit Firebase authentication to session

I'm attempting to implement a "Keep me signed-in" check box when the user signs-in. If the checkbox is checked then the user should remain signed-in until they explicitly sign-out. If not checked, the user should only remain signed-in until they close the app.
The Flutter Firebase Authentication package doesn't have a method for configuring the authentication duration, or at least I've not found a method.
I've tried to listen for when the app is shutting down using the WidgetsBindingObserver's didChangeAppLifecycleState(..) method's AppLifecycleState.detached state. I can see the signOut() method called, but despite this the user remains signed-in the next time they launch the app. I'm not surprised given that the app is in the middle of exiting.
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if( state == AppLifecycleState.detached ){
FirebaseAuth.instance.signOut();
}
}
Am I missing any good options?
By default the Firebase Authentication SDKs persist the authentication state to local storage, and then restore it from there when the app restarts.
If you want the state to not be persisted, you can configure that when the app starts by calling:
await FirebaseAuth.instance.setPersistence(Persistence.NONE);
Also see the FlutterFire documentation on persisting authentication state.
That's because signOut() returns a Future. So you'll have to await it. So, suppose you have a function userSignOut.
Future<void> userSignOut() => FirebaseAuth.instance.signOut();
And you use it on a button...
IconButton(
icon: const Icon(Icons.exit_to_app),
onPressed: () async {
await userSignOut();
},
)
This should solve your issue. If it still doesn't work, provide more relevant code.

createUserWithEmailAndPassword error operation not allowed (firebase auth enabled)

I'm new with flutter and firebase. I'm trying to use createUserWithEmailAndPassword function for firebase but when I try to implement the code it's an infinite loop. I used debug mode of android studio and it shows me the errors ERROR_OPERATION_NOT_ALLOWED : The given sign-in provider is disabled for this Firebase project. Enable it in the Firebase console, under the sign-in method tab of the Auth section. . It seems to be an errors in the firebase authentification but I already enable the authentification with email and password then I don't understand why there is this issue. I copy-paste the json document and I modified the gradle files too as it is mentionned in the google process.
Thanks for the help.
The error says the given sign-in provider is disabled for this Firebase project
You have to enable email and password options in your firebase project.
See screenshots on how to do that below:
1) Go to the authentication tab after clicking your firebase project
2) Select the Sign-In methods tab
3) Enable sign in with email and password
If you are still getting the error, Try running flutter clean in your project.
I hope this helps
FlatButton(onPressed: () async {
if(_formKey.currentState.validate()) {
setState(() => chargement = true);
AuthResult result = await _auth.createUserWithEmailAndPassword(email: email, password: mdp); //here is the issue
await collectionUser.document(_idUser()).setData({
'idUser' : _idUser(),
'nomComplet' : nomComplet,
'emailUser' : email,
});
if(result == null){
setState(() => chargement = true);
}
}
},
color: Colors.amber,
child: Text("inscription"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)
),
),

Listening to changes in firebase auth credentials

I was building an app which requires me to sign in the user with two compulsory methods, the email as well as the phone number as both the type of data is crucial for the proper functioning of the app. I have implemented Firebase email-password based authentication and google sign in into my app along with phone verification.
Now, I have successfully implemented both the methods and managed to link the credentials of phone auth with email and the same is visible on the firebase console but the problem is that I'm not notified of any changes in auth credentials.
Here's the code I've used to determine which page to show depending on the state of snapshot.data
return StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting ||
snapshot.connectionState == ConnectionState.none) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
} else {
if (snapshot.hasError) {
return Scaffold(
body: Center(
child: Text("Error signing in. Please try later"),
),
);
} else if (snapshot.hasData) {
print("signInHandler.dart phone: ${snapshot.data.phoneNumber}");
if (snapshot.data.phoneNumber == null) {
return PhoneSignIn();
}
return MyHomePage();
}
return EmailSignIn();
}
},
);
Now I know as per documentaions, onAuthStateChanged is fired only if there was any sign in or sign out event but is there any way to know that the AuthCredentials have changed so that I can decide the appropriate page to show depending on the data?
However, when I hot reload the app after linking auth credentials, the appropriate screen is displayed i.e MyHomePage(). Before that, the app keeps displaying only the PhoneSignIn() screen ever after successfully linking the credentials.
Getting phone number using google's contacts API did not solve my problem as there are some google accounts which are not associated with any phone number.
I'd be very grateful if someone could point me in the right direction.
singh, you'll need to force refresh the user idToken, getIdToken(true), so as propagate the new values for credentials, claims or providers on the auth user instance. You can read here for more.
In the end, I could not find any out of the box solution for the problem and had to use a bunch of streams and Bloc for managing this state.

Is it possible to delete currentUser firebase authentication user?

I used firebase_auth package to work with flutter. And I used phone authentication to sign in. Everything is working well. But when signout user is not deleted on firebase.
Is it possible to delete firebase user?
RaisedButton(
onPressed: () async {
await FirebaseAuth.instance.signOut();
}
)
I tried this way,
but error is coming..
delete called null
_auth.onAuthStateChanged.listen((currentUser)=>{
currentUser.delete()
}).onError((e)=>print("Error is $e"));
Yes. You must use FirebaseAuth.instance.currentUser.delete() method before (on) signOut() method.
RaisedButton(
onPressed: () async {
FirebaseAuth.instance.currentUser.delete();
await FirebaseAuth.instance.signOut();
}
)
You can't delete the current user after they've signed out, because at that point there is no current user anymore.
But you can prevent this whole chicken-and-egg problem by simply deleting the user without signing out. This should be all that is needed for that:
currentUser.delete()
You can call this operation "logging out" for your users of course, but in code you're simply deleting their account.

Resources