Commit 1e201108 authored by Surya B's avatar Surya B
Browse files

verif email sering buka route sendiri

parent daa21fd8
No related merge requests found
Showing with 285 additions and 28 deletions
+285 -28
......@@ -22,6 +22,9 @@ if (flutterVersionName == null) {
}
apply plugin: 'com.android.application'
// START: FlutterFire Configuration
apply plugin: 'com.google.gms.google-services'
// END: FlutterFire Configuration
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
......@@ -65,4 +68,5 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation platform('com.google.firebase:firebase-bom:29.3.0')
}
{
"project_info": {
"project_number": "1071653908052",
"project_id": "cleon-mobile-deep-link",
"storage_bucket": "cleon-mobile-deep-link.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:1071653908052:android:9ddf727452f31627a947c1",
"android_client_info": {
"package_name": "com.example.cleon_mobile"
}
},
"oauth_client": [
{
"client_id": "1071653908052-ur785kpi0v4vuj0a0aiq6903smlb9a58.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.example.cleon_mobile",
"certificate_hash": "3adb786f6c2e82fb44bfb802145271b916ca41f1"
}
},
{
"client_id": "1071653908052-42s7pp3ig0o49htgq9hd8kho24io3eqp.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyD1s_-s5sTt1DBtkbspwEoeuveuWQvQzMY"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "1071653908052-42s7pp3ig0o49htgq9hd8kho24io3eqp.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
......@@ -24,6 +24,16 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Deep linking -->
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="cleonmobile.page.link" />
<data android:scheme="https" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
......
......@@ -8,6 +8,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.10'
}
}
......
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:1071653908052:ios:f45571c4c2a06035a947c1",
"FIREBASE_PROJECT_ID": "cleon-mobile-deep-link",
"GCM_SENDER_ID": "1071653908052"
}
\ No newline at end of file
......@@ -21,7 +21,12 @@ class EmailVerificationBloc
}
});
on<SendVerificationLink>((event, emit) async {
emit(EmailVerificationLoading());
await userRepository.cekVerifikasiEmail();
emit(EmailUnverificated());
});
on<VerifyingEmail>((event, emit) async {
await userRepository.verifyEmail(event.uri);
});
}
}
......@@ -10,3 +10,15 @@ abstract class EmailVerificationEvent extends Equatable {
class SendVerificationLink extends EmailVerificationEvent {}
class CheckingVerificationStatus extends EmailVerificationEvent {}
class VerifyingEmail extends EmailVerificationEvent {
final Uri uri;
const VerifyingEmail({required this.uri});
@override
List<Object> get props => [uri];
@override
String toString() => 'Verifying to ' + uri.toString();
}
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyAOaIfkLg15PjRkVV-mK-jV80Gi8FvxF9g',
appId: '1:1071653908052:web:c0c177cf22727b24a947c1',
messagingSenderId: '1071653908052',
projectId: 'cleon-mobile-deep-link',
authDomain: 'cleon-mobile-deep-link.firebaseapp.com',
storageBucket: 'cleon-mobile-deep-link.appspot.com',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyD1s_-s5sTt1DBtkbspwEoeuveuWQvQzMY',
appId: '1:1071653908052:android:9ddf727452f31627a947c1',
messagingSenderId: '1071653908052',
projectId: 'cleon-mobile-deep-link',
storageBucket: 'cleon-mobile-deep-link.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyAt3V_CizIONlfTHUsxY8gEfb-ytom12ao',
appId: '1:1071653908052:ios:f45571c4c2a06035a947c1',
messagingSenderId: '1071653908052',
projectId: 'cleon-mobile-deep-link',
storageBucket: 'cleon-mobile-deep-link.appspot.com',
androidClientId: '1071653908052-ur785kpi0v4vuj0a0aiq6903smlb9a58.apps.googleusercontent.com',
iosClientId: '1071653908052-8ooecgfveennvrguokvb0q1dkcjk6qep.apps.googleusercontent.com',
iosBundleId: 'n',
);
}
......@@ -7,8 +7,11 @@ import 'package:cleon_mobile/repositories/user_repositories.dart';
import 'package:cleon_mobile/routes.dart';
import 'package:cleon_mobile/views/auth/email_verification.dart';
import 'package:cleon_mobile/views/dashboard.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
class SimpleBlocObserver extends BlocObserver {
@override
......@@ -30,7 +33,11 @@ class SimpleBlocObserver extends BlocObserver {
}
}
void main() {
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
final UserRepository userRepository = UserRepository();
BlocOverrides.runZoned(
() => runApp(BlocProvider<AuthBloc>(
......@@ -43,9 +50,15 @@ void main() {
blocObserver: SimpleBlocObserver());
}
class MyApp extends StatelessWidget {
class MyApp extends StatefulWidget {
final UserRepository userRepository;
const MyApp({Key? key, required this.userRepository}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
final routeGenerator = RouteGenerator();
......@@ -58,14 +71,13 @@ class MyApp extends StatelessWidget {
if (state is AuthAuthenticated) {
return BlocProvider(
create: (context) =>
EmailVerificationBloc(userRepository: userRepository)
EmailVerificationBloc(userRepository: widget.userRepository)
..add(CheckingVerificationStatus()),
child: BlocBuilder<EmailVerificationBloc, EmailVerificationState>(
builder: (context, state) {
if (state is EmailVerificated) {
return App();
}
if (state is EmailUnverificated) {
} else if (state is EmailUnverificated) {
return EmailVerification();
}
return Scaffold(
......@@ -77,6 +89,9 @@ class MyApp extends StatelessWidget {
CircularProgressIndicator(
color: Colors.white,
),
SizedBox(
height: 15,
),
Text(
"Loading",
style: TextStyle(color: Colors.white),
......@@ -88,13 +103,11 @@ class MyApp extends StatelessWidget {
},
),
);
}
if (state is AuthUnauthenticated) {
} else if (state is AuthUnauthenticated) {
return Dashboard(
userRepository: userRepository,
userRepository: widget.userRepository,
);
}
if (state is AuthLoading) {
} else if (state is AuthLoading) {
return Scaffold(
backgroundColor: Color(0xff2F2E41),
body: Center(
......@@ -104,6 +117,9 @@ class MyApp extends StatelessWidget {
CircularProgressIndicator(
color: Colors.white,
),
SizedBox(
height: 15,
),
Text(
"Loading",
style: TextStyle(color: Colors.white),
......@@ -122,6 +138,9 @@ class MyApp extends StatelessWidget {
CircularProgressIndicator(
color: Colors.white,
),
SizedBox(
height: 15,
),
Text(
"Loading",
style: TextStyle(color: Colors.white),
......
......@@ -84,4 +84,11 @@ class UserRepository {
return false;
}
Future<void> verifyEmail(Uri uri) async {
final prefs = await SharedPreferences.getInstance();
String? token = prefs.getString("token");
await http.get(uri, headers: {'Authorization': 'Bearer $token'});
}
}
......@@ -42,7 +42,13 @@ class RouteGenerator {
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(child: Text("Not Found")),
body: Center(
child: ElevatedButton(
child: Text('back'),
onPressed: () {
Navigator.defaultRouteName;
},
)),
));
}
}
......
// ignore_for_file: prefer_const_constructors
import 'package:cleon_mobile/bloc/email_verification_bloc.dart';
import 'package:cleon_mobile/utils/logo.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class EmailVerification extends StatelessWidget {
class EmailVerification extends StatefulWidget {
const EmailVerification({Key? key}) : super(key: key);
@override
State<EmailVerification> createState() => _EmailVerificationState();
}
class _EmailVerificationState extends State<EmailVerification> {
@override
void initState() {
// TODO: implement initState
super.initState();
initDynamicLink();
}
void initDynamicLink() async {
FirebaseDynamicLinks.instance.onLink.listen((event) {
Uri link = event.link;
// BlocProvider.of<EmailVerificationBloc>(context)
// .add(VerifyingEmail(uri: link));
print(link.toString());
Navigator.defaultRouteName;
});
}
// void handleLinkData(PendingDynamicLinkData data) {
// final Uri? uri = data.link;
// print(data.link.toString());
// if (uri != null) {
// final queryParams = uri.queryParameters;
// if (queryParams.isNotEmpty) {
// String? userName = queryParams["username"];
// // verify the username is parsed correctly
// print("My users username is: $userName");
// }
// }
// }
@override
Widget build(BuildContext context) {
return Scaffold(
......@@ -48,7 +86,10 @@ class EmailVerification extends StatelessWidget {
borderRadius: BorderRadius.circular(10),
),
),
onPressed: () {},
onPressed: () {
BlocProvider.of<EmailVerificationBloc>(context)
.add(SendVerificationLink());
},
child: Text(
"Kirim Link Verifikasi Ulang",
style: TextStyle(color: Colors.black87),
......
......@@ -3,7 +3,6 @@
import 'package:cleon_mobile/bloc/login_bloc.dart';
import 'package:cleon_mobile/repositories/user_repositories.dart';
import 'package:cleon_mobile/utils/logo.dart';
import 'package:cleon_mobile/views/auth/email_verification.dart';
import 'package:cleon_mobile/views/auth/lupa_password.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
......
......@@ -24,20 +24,7 @@ class Dashboard extends StatelessWidget {
userRepository: userRepository,
);
} else if (state is SignUpState) {
return AnimatedSwitcher(
switchOutCurve: Threshold(0),
duration: Duration(milliseconds: 1000),
transitionBuilder: (Widget child, Animation<double> animation) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 0.25),
end: Offset.zero,
).animate(animation),
child: child,
);
},
child: SignUp(userRepository: userRepository),
);
return SignUp(userRepository: userRepository);
} else {
return Scaffold(
backgroundColor: Color(0xff2F2E41),
......
......@@ -106,6 +106,41 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.1"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.5"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.2"
firebase_dynamic_links:
dependency: "direct main"
description:
name: firebase_dynamic_links
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.3"
firebase_dynamic_links_platform_interface:
dependency: transitive
description:
name: firebase_dynamic_links_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.2+3"
flutter:
dependency: "direct main"
description: flutter
......@@ -156,6 +191,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
get:
dependency: "direct main"
description:
name: get
url: "https://pub.dartlang.org"
source: hosted
version: "4.6.1"
http:
dependency: "direct main"
description:
......
......@@ -34,6 +34,10 @@ dependencies:
equatable: ^2.0.3
shared_preferences: ^2.0.13
http: ^0.13.4
get: ^4.6.1
firebase_dynamic_links: ^4.1.3
firebase_core: ^1.14.1
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment