Flutter/Firebase Connecting to Google Takes Too Long - flutter

Trying to connect to Google, which finally worked but after 525 seconds (over 8 min). There has to be reason for this issue, but I can't figure it out.
Thanks in advance for your suggestions!!!!
Here is my main.dart file:
import 'dart:developer';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'auth.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter SignIn Too Long',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter SignIn Too Long'),
);
}
}
/// MyHomePage
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late User user;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
floatingActionButton: FloatingActionButton(
onPressed: _googleSignIn,
child: const Icon(Icons.access_time),
),
);
}
///Sign Into Google
void _googleSignIn() {
final stopwatch = Stopwatch();
DateTime dateTime;
dateTime = DateTime.now();
log('SignInWithGoogle: START: ${dateTime.toString()}' );
stopwatch.start();
signInWithGoogle().then((user) => {
log('SignInWithGoogle: END: '
'${dateTime.add(Duration(
milliseconds: stopwatch.elapsedMilliseconds)).toString()}'),
log('SignInWithGoogle: ELAPSED TIME: '
'${Duration(milliseconds: stopwatch.elapsedMilliseconds).inSeconds.
toString()} SECONDS'),
log('SignInWithGoogle: NAME: ${user.displayName!}' ),
log('SignInWithGoogle: EMAIL: ${user.email!}' ),
//sign out
signOutGoogle(),
});
}
}
Here is the auth.dart file, performing the actual connection:
import 'dart:developer';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
//setup firebase and google instances
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
///Async - Sign In with Google
Future<User> signInWithGoogle() async {
try {
//Google authentication
final GoogleSignInAccount? account = await googleSignIn.signIn();
final GoogleSignInAuthentication? authentication =
await account?.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
idToken: authentication?.idToken,
accessToken: authentication?.accessToken);
//firebase authentication
final UserCredential authResult =
await firebaseAuth.signInWithCredential(credential);
final User? user = authResult.user;
assert(await user?.getIdToken() != null);
final User currentUser = firebaseAuth.currentUser!;
assert(currentUser.uid == user?.uid);
return currentUser;
} on Exception catch (e) {
log(e.toString());
rethrow;
}
}
//Sign Out
void signOutGoogle() async {
await firebaseAuth.signOut();
await googleSignIn.signOut();
}
I've added all the needed (at least what I know) build.gradle and pubspec.yaml changes.
Here is the Run console:
Launching lib\main.dart on sdk gphone64 x86 64 in debug mode...
Running Gradle task 'assembleDebug'...
√ Built build\app\outputs\flutter-apk\app-debug.apk.
Installing build\app\outputs\flutter-apk\app.apk...
Debug service listening on ws://127.0.0.1:54147/Xzu_ZHSI-6M=/ws
Syncing files to device sdk gphone64 x86 64...
D/EGL_emulation(14666): app_time_stats: avg=1734.21ms min=4.61ms max=5034.20ms count=3
[log] SignInWithGoogle: START: 2022-10-23 16:11:04.138638
D/CompatibilityChangeReporter(14666): Compat change id reported: 78294732; UID 10212; state: DISABLED
D/EGL_emulation(14666): app_time_stats: avg=3204.18ms min=2.90ms max=44750.13ms count=14
W/System (14666): Ignoring header X-Firebase-Locale because its value was null.
W/System (14666): Ignoring header X-Firebase-Locale because its value was null.
D/FirebaseAuth(14666): Notifying id token listeners about user ( FINmAp3zonflqrkhsXDgBIu2dsA2 ).
D/FirebaseAuth(14666): Notifying auth state listeners about user ( FINmAp3zonflqrkhsXDgBIu2dsA2 ).
[log] SignInWithGoogle: END: 2022-10-23 16:19:49.896638
D/FirebaseAuth(14666): Notifying id token listeners about a sign-out event.
D/FirebaseAuth(14666): Notifying auth state listeners about a sign-out event.
[log] SignInWithGoogle: ELAPSED TIME: 525 SECONDS
[log] SignInWithGoogle: NAME: <valid my name>
[log] SignInWithGoogle: EMAIL: <valid my email>

Related

Google OAuth 2.0 failing with Error 400: invalid_request for some client_id, Can't Sign in because 'App' sent an invalid request

I have an Flutter app that uses googleapis_auth 1.3.1 and googleapis 9.2.0 .
What I have done:
enabled the Google Calender API
connect Flutter Project to Firebase
and set up with basic template.
But I am getting the following error:
Here is my code:
`
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:googleapis/calendar/v3.dart' as cal;
import 'package:url_launcher/url_launcher.dart';
import 'gCalender/calendar_client.dart';
import 'secert.dart';
import 'package:googleapis_auth/auth_io.dart';
void main() async {
//firebase initialize
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
//google apis init
var clientID = ClientId(Secret.getId(),"");
var scopes = [cal.CalendarApi.calendarEventsScope];
await clientViaUserConsent(clientID, scopes, prompt).then((AuthClient client) async {
CalendarClient.calendar = cal.CalendarApi(client);
});
runApp(const MyApp());
}
void prompt(String url) async {
if (!await launchUrl(Uri.parse(url))) {
throw 'Could not launch $url';
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Social Login',
theme: theme(),
debugShowCheckedModeBanner: false,
initialRoute: SplashScreen.routeName,
// home: const SplashScreen(),
routes: routes,
);
}
}
`
I explored the internet but couldn't find any solution.
if you use emulator, try the app in real phone, cuz some times firebase services not working well in the virtual phones

How can I call an Encrypted Hive Box to a class?

I am needing to encrypt a hive box, in which the box 'user_api' is to be called in Api_Page_() to receive user input to store inside said box. However, the encryptedBox is not defined within the class. The Hive Docs display the encryption code is to be done inside of the main() function, which I have done, but I am unsure of how to take the box outside of main().
Any help or advice is greatly appreciated!
My Code:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// HIVE ENCRYPTION----------------------------------------
const secureStorage = FlutterSecureStorage();
final encryptionKey = await secureStorage.read(key: 'key');
if (encryptionKey == null) {
final key = Hive.generateSecureKey();
await secureStorage.write(
key: 'key',
value: base64Encode(key),
);
}
final key = await secureStorage.read(key: 'key');
final encryptKey = base64Url.decode(key);
print('Encryption key: $encryptKey');
// HIVE ENCRYPTION----------------------------------------
// HIVE INIT---------------------------------------------
Directory directory = await getApplicationDocumentsDirectory();
Hive.init(directory.path);
await Hive.initFlutter();
final encryptedBox = Hive.openBox<String>('user_api', encryptionCipher: HiveAesCipher(encryptKey)); // Initially Opens Box on App Start
// HIVE INIT---------------------------------------------
runApp(myApp());
}
class myApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false, // Removes Debug Banner. [Delete before app release]
title: 'App Title Placeholder',
home: API_Page_() // Calls API_Page_ class from api_page.dart
);
}
}
class API_Page_ extends StatelessWidget {
const API_Page_({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: RaisedButton(onPressed: () { var eBox = encryptedBox<String>('user_api');
},
)
);
}
}

How to make me Signout in Flutter

I am creating a Login , Logout Page in flutter when i use Stream and Provider . I get Some Errors.
Help me out of this
in the main.dart when i use the StreamProvider it says the intial data cannot be null, according to my Tutorial there is no intialdata and in auth.dart when i use the authStatchanges().map it gives me 'The argument type 'Userid Function(User)' can't be assigned to the parameter type 'Userid Function(User?)'
Error Places - auth change user stream & and StreamProvider in main.dart
Thanks
Auth.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:wasthu/Services/user.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
//create userobject based on firebase user
Userid? _userFromFirebaseUser(User user) {
return user != null ? Userid(uid: user.uid) : null;
}
// auth change user stream
Stream<Userid> get user {
return _auth
.authStateChanges()
.map((User user) => _userFromFirebaseUser(user));
}
//sign in anon
Future signInAnon() async {
try {
UserCredential result = await _auth.signInAnonymously();
User? user = result.user;
return _userFromFirebaseUser(user!);
} catch (e) {
print(e.toString());
return null;
}
}
//signout
Future signOut() async {
try {
return await _auth.signOut();
} catch (e) {
print(e.toString());
return null;
}
}
}
main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wasthu/Screens/Home/wrapper.dart';
import 'package:wasthu/Services/auth.dart';
import 'package:wasthu/Services/user.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MaterialApp(
home: MyApp(),
debugShowCheckedModeBanner: false,
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamProvider<Userid>.value(
value: AuthService().user,
initialData: null,
child: MaterialApp(
home: Wrapper(),
),
);
}
}
user.dart
class Userid {
final String uid;
Userid({required this.uid});
}

Authorization_RequestDenied , message : Insufficient privileges to complete the operation

I'm tring to get data of signed in user from microsoft azure using microsoft graph api,
i'm getting access token and also login successfully,
but i'm getting error as : "Insufficient privileges to complete the operation."
My Code
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:aad_oauth/aad_oauth.dart';
import 'package:aad_oauth/model/config.dart';
import 'package:exim_bank_leave_app/Utils/AppTheme.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Screens/Listing.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: MyTheme.darkTheme(context),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
static var user;
static final Config config = Config(
tenant: 'f6------------------38',
clientId: 'cba-----------------f5',
scope: 'openid profile offline_access',
redirectUri: 'https://login.microsoftonline.com/common/oauth2/nativeclient',
);
static final AadOAuth oauth = AadOAuth(config);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SharedPreferences prefs;
static final String accessToken = accessToken;
var token;
#override
void initState() {
super.initState();
loadData();
}
#override
Widget build(BuildContext context) {
// adjust window size for browser login
var screenSize = MediaQuery.of(context).size;
var rectSize =
Rect.fromLTWH(0.0, 25.0, screenSize.width, screenSize.height - 25);
MyHomePage.oauth.setWebViewScreenSize(rectSize);
return Scaffold(
body: Container(),
);
}
loadData() async {
var auth = MyHomePage.oauth;
await auth.login();
var accessToken = await auth.getAccessToken();
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => Listing()));
prefs = await SharedPreferences.getInstance();
while (prefs == null || accessToken == null) continue;
final String idToken = await auth.getIdToken();
setState(() {
prefs.setString('token', idToken);
});
print('Token $accessToken');
final graphResponse = await http.get('https://graph.microsoft.com/v1.0/me',
headers: {HttpHeaders.authorizationHeader: "Bearer $accessToken"});
print(graphResponse.body.toString());
print(graphResponse.statusCode);
}
static void logout() async {
await MyHomePage.oauth.logout();
}
}
Error : I/flutter (29743): {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2021-10-04T10:28:54","request-id":"3b12c615-47f1-4d07-ab4e-b6f4907a5b11","client-request-id":"3b12c615-47f1-4d07-ab4e-b6f4907a5b11"}}}
Based on your code 'https://graph.microsoft.com/v1.0/me' you are using the /me
When Calling the /me endpoint requires a signed-in user and therefore a delegated permission. Application permissions are not supported when using the /me endpoint .So Add the Delegated permission to call ApI
Delegated permissions are
User.Read,
User.ReadWrite,
User.ReadBasic.All,
User.Read.All,
User.ReadWrite.All,
Directory.Read.All,
Directory.ReadWrite.All,
Directory.AccessAsUser.All
To add the permission
1) Under an application's API permissions page, choose Add a permission.
2) select Microsoft Graph.
3) Choose the Delegated permission. And Search all the permission and Click on the Add Permission.
For more details refer this document

Google SignUp/ SignIn with Flutter + Back4App

Below is the used code:
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
Future<void> _signUpGoogle() async {
// loading = true;
final GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: ['email', 'https://www.googleapis.com/auth/contacts.readonly']);
sigInGoogle() async {
GoogleSignInAccount account = await _googleSignIn.signIn();
GoogleSignInAuthentication authentication = await account.authentication;
final ParseResponse response = await ParseUser.loginWith(
'google',
google(_googleSignIn.currentUser.id,
authentication.accessToken.toString(), authentication.idToken));
// print('response.error' + response.error.toString());
// print('response.results' + response.results.toString());
// print('response.results' + response.statusCode.toString());
print(response.toString());
if (response.success) {
print('parse google signin successs');
print(response.success);
} else {
print('parse google SignIn Failed');
print('response.error: ' + response.error.toString());
// print(google(_googleSignIn.currentUser.id,
// authentication.accessToken.toString(), authentication.idToken));
}
}
sigInGoogle();
}
#override
Widget build(BuildContext context) {
return Center(
child: IconButton(
icon: Icon(Icons.login),
onPressed: _signUpGoogle,
),
);
}
}
Below are the logs:
I/flutter (23392): Instance of 'ParseResponse'
I/flutter (23392): parse google SignIn Failed
I/flutter (23392): response.error:
I/flutter (23392): ----
I/flutter (23392): ParseException (Type: ObjectNotFound) :
I/flutter (23392): Code: 101
I/flutter (23392): Message: Google auth is invalid for this user.----
Please help to resolve this.
Looks like your parameters are the wrong way around when passing to the 'google' data type. The parameters are;
Map<String, dynamic> google(String token, String id, String idToken)
Using your code but passing through in this order,
google(authentication.accessToken.toString(), _googleSignIn.currentUser!.id, authentication.idToken!));
Does the trick for me