I want my Login Screen to be shown if a user isn't logged in and the MainPage to be shown if the user is logged in from the device. For GitHub authentication, the browser is being opened and once the authentication is successful, I want the user to be redirected to the MainPage and not the login screen, but with my code, the user is redirected again to the Login Screen. The code for the login_screen.dart is,
import 'package:flutter/material.dart';
import 'package:githubapp/custom_widgets/custom_login_page.dart';
import 'package:githubapp/screens/user_initial_screen.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:async';
import 'package:uni_links/uni_links.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
StreamSubscription _subs;
@override
void initState() {
_initDeepLinkListener();
super.initState();
}
@override
void dispose() {
_disposeDeepLinkListener();
super.dispose();
}
void _initDeepLinkListener() async {
_subs = getLinksStream().listen((String link) {
_checkDeepLink(link);
}, cancelOnError: true);
}
void _checkDeepLink(String link) {
if (link != null) {
String code = link.substring(link.indexOf(RegExp('code=')) + 5);
loginWithGitHub(code)
.then((firebaseUser) {
print("LOGGED IN AS: " + firebaseUser.displayName);
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context){
return MainPage();
}));
}).catchError((e) {
print("LOGIN ERROR: " + e.toString());
});
}
}
void _disposeDeepLinkListener() {
if (_subs != null) {
_subs.cancel();
_subs = null;
}
}
@override
Widget build(BuildContext context) {
return customLoginPage(context);
}
}
const String GITHUB_CLIENT_ID = "My Client Id";
const String GITHUB_CLIENT_SECRET = "My Client Secret";
void onClickGitHubLoginButton() async {
const String url = "https://github.com/login/oauth/authorize" +
"?client_id=" + GITHUB_CLIENT_ID +
"&scope=public_repo%20read:user%20user:email";
if (await canLaunch(url)) {
await launch(
url,
forceSafariVC: false,
forceWebView: false,
);
} else {
print("CANNOT LAUNCH THIS URL!");
}
}
Future<FirebaseUser> loginWithGitHub(String code) async {
//ACCESS TOKEN REQUEST
final response = await http.post(
"https://github.com/login/oauth/access_token",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: jsonEncode(GitHubLoginRequest(
clientId: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
code: code,
)),
);
GitHubLoginResponse loginResponse =
GitHubLoginResponse.fromJson(json.decode(response.body));
final AuthCredential credential = GithubAuthProvider.getCredential(
token: loginResponse.accessToken,
);
final FirebaseUser user = (await FirebaseAuth.instance.signInWithCredential(credential)).user;
return user;
}
class GitHubLoginRequest {
String clientId;
String clientSecret;
String code;
GitHubLoginRequest({this.clientId, this.clientSecret, this.code});
dynamic toJson() => {
"client_id": clientId,
"client_secret": clientSecret,
"code": code,
};
}
class GitHubLoginResponse {
String accessToken;
String tokenType;
String scope;
GitHubLoginResponse({this.accessToken, this.tokenType, this.scope});
factory GitHubLoginResponse.fromJson(Map<String, dynamic> json) =>
GitHubLoginResponse(
accessToken: json["access_token"],
tokenType: json["token_type"],
scope: json["scope"],
);
}
The code on the main.dart is,
import 'package:flutter/material.dart';
import 'package:githubapp/auth/login_screen.dart';
import 'package:githubapp/screens/user_initial_screen.dart';
import 'package:githubapp/screens/user_profile_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
// This widget is the root of your application.
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String routeToMainPage = 'mainPage';
String routeToLoginPage = 'loginPage';
String routeInitial = '';
getCurrentUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
return user;
}
@override
void initState() {
// TODO: implement initState
super.initState();
if(getCurrentUser() != null){
routeInitial = routeToMainPage;
} else {
routeInitial = routeToLoginPage;
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'GitHub',
initialRoute: '/${routeInitial}',
routes: {
'/mainPage': (context) => MainPage(),
'/loginPage': (context) => LoginPage(),
'/userprofile': (context) => UserProfilePage(),
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
}
}
The code where the MainPage() function is present is,
import 'package:flutter/material.dart';
import 'package:githubapp/custom_widgets/custom_appbar.dart';
class MainPage extends StatefulWidget {
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
return GestureDetector(
child: Scaffold(
appBar: customAppBar(context),
// body: ,
),
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
);
}
}
For the Authorization callback URL, which we have to enter while getting the ClientId and ClientSecret from GitHub is, appname://auth?code=auth/