Skip to content

Commit e2e82c3

Browse files
committed
Implemented google sign in
1 parent 5b3807c commit e2e82c3

17 files changed

+334
-87
lines changed

README.md

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
# huthaifa_glints
1+
# Huthaifa's Submission for Glints
22

3-
A new Flutter project.
3+
A Simple Twitter Clone for one user.
44

55
## Getting Started
66

77
This project is a starting point for a Flutter application.
88

9-
A few resources to get you started if this is your first Flutter project:
109

11-
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12-
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
1310

14-
For help getting started with Flutter, view our
15-
[online documentation](https://flutter.dev/docs), which offers tutorials,
16-
samples, guidance on mobile development, and a full API reference.

android/app/build.gradle

+4-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ if (flutterVersionName == null) {
2424
apply plugin: 'com.android.application'
2525
apply plugin: 'kotlin-android'
2626
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27+
apply plugin: 'com.google.gms.google-services'
2728

2829
android {
2930
compileSdkVersion 30
@@ -34,8 +35,8 @@ android {
3435

3536
defaultConfig {
3637
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
37-
applicationId "com.example.huthaifa_glints"
38-
minSdkVersion 16
38+
applicationId "com.huthaifa.glints"
39+
minSdkVersion 21
3940
targetSdkVersion 30
4041
versionCode flutterVersionCode.toInteger()
4142
versionName flutterVersionName
@@ -56,4 +57,5 @@ flutter {
5657

5758
dependencies {
5859
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
60+
5961
}

android/app/google-services.json

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"project_info": {
3+
"project_number": "1033663828555",
4+
"project_id": "cloudfunctiontests-6c4ca",
5+
"storage_bucket": "cloudfunctiontests-6c4ca.appspot.com"
6+
},
7+
"client": [
8+
{
9+
"client_info": {
10+
"mobilesdk_app_id": "1:1033663828555:android:9226d118c3501b8ebcf3ce",
11+
"android_client_info": {
12+
"package_name": "com.huthaifa.glints"
13+
}
14+
},
15+
"oauth_client": [
16+
{
17+
"client_id": "1033663828555-2oiogptccfhb14186a57v5gfuphiq32c.apps.googleusercontent.com",
18+
"client_type": 3
19+
}
20+
],
21+
"api_key": [
22+
{
23+
"current_key": "AIzaSyAq2rWoNNB1S4eEUkhV9W23N8wWfVtQPLI"
24+
}
25+
],
26+
"services": {
27+
"appinvite_service": {
28+
"other_platform_oauth_client": [
29+
{
30+
"client_id": "1033663828555-2oiogptccfhb14186a57v5gfuphiq32c.apps.googleusercontent.com",
31+
"client_type": 3
32+
}
33+
]
34+
}
35+
}
36+
}
37+
],
38+
"configuration_version": "1"
39+
}

android/app/src/debug/AndroidManifest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
package="com.example.huthaifa_glints">
2+
package="com.huthaifa.glints">
33
<!-- Flutter needs it to communicate with the running application
44
to allow setting breakpoints, to provide hot reload, etc.
55
-->

android/app/src/main/AndroidManifest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
package="com.example.huthaifa_glints">
2+
package="com.huthaifa.glints">
33
<application
44
android:label="huthaifa_glints"
55
android:icon="@mipmap/ic_launcher">

android/app/src/main/kotlin/com/example/huthaifa_glints/MainActivity.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.example.huthaifa_glints
1+
package com.huthaifa.glints
22

33
import io.flutter.embedding.android.FlutterActivity
44

android/app/src/profile/AndroidManifest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
package="com.example.huthaifa_glints">
2+
package="com.huthaifa.glints">
33
<!-- Flutter needs it to communicate with the running application
44
to allow setting breakpoints, to provide hot reload, etc.
55
-->

android/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ buildscript {
88
dependencies {
99
classpath 'com.android.tools.build:gradle:4.1.0'
1010
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11+
classpath 'com.google.gms:google-services:4.3.5'
1112
}
1213
}
1314

lib/functions/login_functions.dart

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import 'dart:async';
2+
import 'package:cloud_firestore/cloud_firestore.dart';
3+
import 'package:com_huthaifa_glints/models/user_model.dart';
4+
import 'package:firebase_auth/firebase_auth.dart';
5+
import 'package:google_sign_in/google_sign_in.dart';
6+
7+
class LoginFunctions {
8+
///Trigers sign in with google function
9+
Future<UserCredential?> signInWithGoogle() async {
10+
// Triggers the authentication flow
11+
try {
12+
final GoogleSignInAccount? googleUser = await (GoogleSignIn().signIn());
13+
14+
// Obtain the auth details from the request
15+
final GoogleSignInAuthentication googleAuth = await googleUser!.authentication;
16+
17+
// Create a new credential
18+
final GoogleAuthCredential credential = GoogleAuthProvider.credential(
19+
accessToken: googleAuth.accessToken,
20+
idToken: googleAuth.idToken,
21+
) as GoogleAuthCredential;
22+
23+
// Once signed in, return the UserCredential
24+
return await FirebaseAuth.instance.signInWithCredential(credential);
25+
} catch (e) {
26+
print(e);
27+
return null;
28+
}
29+
}
30+
31+
CollectionReference users = FirebaseFirestore.instance.collection('users');
32+
33+
///Retrieves user from firebase, or creates a new one if the user doesn't exsits.
34+
Future<AppUser> loginuser() async {
35+
UserCredential? _userCredential = await signInWithGoogle();
36+
if (_userCredential == null) return AppUser();
37+
return await (users
38+
.where('email', isEqualTo: _userCredential.user?.email)
39+
.get()
40+
.then((QuerySnapshot firebaseResult) async {
41+
//if the user exists, we will get one value, and not an empty "docs" list, we take the first index, because it's only one result.
42+
if (firebaseResult.docs.isNotEmpty) {
43+
return AppUser.fromMap(firebaseResult.docs[0].data());
44+
} else {
45+
return await createUser(_userCredential);
46+
}
47+
}).catchError((error) async {
48+
print('Failed to sign in or signup, error: $error');
49+
}));
50+
}
51+
52+
Future<AppUser> createUser(UserCredential userCredential) async {
53+
AppUser _appUser = AppUser();
54+
User? _firebaseUser = userCredential.user;
55+
if (_firebaseUser == null) return _appUser;
56+
57+
_appUser.id = _firebaseUser.uid;
58+
_appUser.email = _firebaseUser.email ?? "error in email";
59+
_appUser.userName = _firebaseUser.displayName ?? "error in usename";
60+
_appUser.image =
61+
_firebaseUser.photoURL ?? 'https://cdn.iconscout.com/icon/premium/png-256-thumb/verified-phone-890923.png';
62+
63+
await users.doc(_appUser.id).set(_appUser.toMap());
64+
return _appUser;
65+
}
66+
67+
//Signs out user from google and current FirebaseAuth instance
68+
Future<void> signOut() async {
69+
await GoogleSignIn().signOut();
70+
await FirebaseAuth.instance.signOut();
71+
72+
print("User Signed Out");
73+
}
74+
}

lib/main.dart

+33-71
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,75 @@
1+
import 'package:com_huthaifa_glints/screens/login/login_screen.dart';
2+
import 'package:firebase_core/firebase_core.dart';
13
import 'package:flutter/material.dart';
4+
import 'package:provider/provider.dart';
25

3-
void main() {
6+
import 'provider/login_provider.dart';
7+
8+
void main() async {
9+
WidgetsFlutterBinding.ensureInitialized();
10+
await Firebase.initializeApp();
11+
print('💪🐘💪 GLINTSARS... WE GOT THIS 💪🐘💪');
412
runApp(MyApp());
513
}
614

715
class MyApp extends StatelessWidget {
8-
// This widget is the root of your application.
916
@override
1017
Widget build(BuildContext context) {
11-
return MaterialApp(
12-
title: 'Flutter Demo',
13-
theme: ThemeData(
14-
// This is the theme of your application.
15-
//
16-
// Try running your application with "flutter run". You'll see the
17-
// application has a blue toolbar. Then, without quitting the app, try
18-
// changing the primarySwatch below to Colors.green and then invoke
19-
// "hot reload" (press "r" in the console where you ran "flutter run",
20-
// or simply save your changes to "hot reload" in a Flutter IDE).
21-
// Notice that the counter didn't reset back to zero; the application
22-
// is not restarted.
23-
primarySwatch: Colors.blue,
18+
return ChangeNotifierProvider(
19+
create: (ctx) => LoginState(),
20+
child: MaterialApp(
21+
title: 'Huthaifa\'s Twitter Clone',
22+
debugShowCheckedModeBanner: false,
23+
theme: ThemeData(
24+
primarySwatch: Colors.blue,
25+
),
26+
home: Consumer<LoginState>(builder: (context, loginState, __) {
27+
return loginState.isSignedIn ? MyHomePage(title: 'Huthaifa\'s Twitter Clone') : LoginPage();
28+
}),
29+
onGenerateRoute: (RouteSettings settings) {
30+
Map<dynamic, dynamic> routes = {};
31+
WidgetBuilder builder = routes[settings.name]!;
32+
33+
return MaterialPageRoute(builder: (ctx) => builder(ctx));
34+
},
2435
),
25-
home: MyHomePage(title: 'Flutter Demo Home Page'),
2636
);
2737
}
2838
}
2939

3040
class MyHomePage extends StatefulWidget {
3141
MyHomePage({Key? key, this.title}) : super(key: key);
3242

33-
// This widget is the home page of your application. It is stateful, meaning
34-
// that it has a State object (defined below) that contains fields that affect
35-
// how it looks.
36-
37-
// This class is the configuration for the state. It holds the values (in this
38-
// case the title) provided by the parent (in this case the App widget) and
39-
// used by the build method of the State. Fields in a Widget subclass are
40-
// always marked "final".
41-
4243
final String? title;
4344

4445
@override
4546
_MyHomePageState createState() => _MyHomePageState();
4647
}
4748

4849
class _MyHomePageState extends State<MyHomePage> {
49-
int _counter = 0;
50-
51-
void _incrementCounter() {
52-
setState(() {
53-
// This call to setState tells the Flutter framework that something has
54-
// changed in this State, which causes it to rerun the build method below
55-
// so that the display can reflect the updated values. If we changed
56-
// _counter without calling setState(), then the build method would not be
57-
// called again, and so nothing would appear to happen.
58-
_counter++;
59-
});
60-
}
61-
6250
@override
6351
Widget build(BuildContext context) {
64-
// This method is rerun every time setState is called, for instance as done
65-
// by the _incrementCounter method above.
66-
//
67-
// The Flutter framework has been optimized to make rerunning build methods
68-
// fast, so that you can just rebuild anything that needs updating rather
69-
// than having to individually change instances of widgets.
7052
return Scaffold(
7153
appBar: AppBar(
72-
// Here we take the value from the MyHomePage object that was created by
73-
// the App.build method, and use it to set our appbar title.
7454
title: Text(widget.title!),
7555
),
7656
body: Center(
77-
// Center is a layout widget. It takes a single child and positions it
78-
// in the middle of the parent.
7957
child: Column(
80-
// Column is also a layout widget. It takes a list of children and
81-
// arranges them vertically. By default, it sizes itself to fit its
82-
// children horizontally, and tries to be as tall as its parent.
83-
//
84-
// Invoke "debug painting" (press "p" in the console, choose the
85-
// "Toggle Debug Paint" action from the Flutter Inspector in Android
86-
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
87-
// to see the wireframe for each widget.
88-
//
89-
// Column has various properties to control how it sizes itself and
90-
// how it positions its children. Here we use mainAxisAlignment to
91-
// center the children vertically; the main axis here is the vertical
92-
// axis because Columns are vertical (the cross axis would be
93-
// horizontal).
9458
mainAxisAlignment: MainAxisAlignment.center,
9559
children: <Widget>[
9660
Text(
97-
'You have pushed the button this many times:',
98-
),
99-
Text(
100-
'$_counter',
101-
style: Theme.of(context).textTheme.headline4,
61+
'Welcome to twitter',
10262
),
10363
],
10464
),
10565
),
10666
floatingActionButton: FloatingActionButton(
107-
onPressed: _incrementCounter,
108-
tooltip: 'Increment',
109-
child: Icon(Icons.add),
110-
), // This trailing comma makes auto-formatting nicer for build methods.
67+
onPressed: () {},
68+
tooltip: "Create Tweet",
69+
child: Icon(
70+
Icons.add_circle,
71+
semanticLabel: "Create Tweet",
72+
)), // This trailing comma makes auto-formatting nicer for build methods.
11173
);
11274
}
11375
}

0 commit comments

Comments
 (0)