From 309b37a677a729cb680859cdbd7ca3bd7bd3311e Mon Sep 17 00:00:00 2001 From: chamod udara Date: Wed, 24 Jul 2024 18:54:39 +0530 Subject: [PATCH] add user singup and singin verifications with firebase --- lib/main.dart | 2 +- lib/pages/homepage.dart | 19 +++ lib/pages/login_page.dart | 23 +++- lib/pages/sing_up_page.dart | 83 ++++++++---- lib/service/authentication.dart | 68 ++++++++-- lib/service/media.dart | 13 ++ lib/service/storage.dart | 26 ++++ linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 120 ++++++++++++++++++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 14 files changed, 329 insertions(+), 37 deletions(-) create mode 100644 lib/pages/homepage.dart create mode 100644 lib/service/media.dart create mode 100644 lib/service/storage.dart diff --git a/lib/main.dart b/lib/main.dart index 01f8d7b..a0ebf46 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -38,7 +38,7 @@ class MyApp extends StatelessWidget { theme: ThemeData.dark() .copyWith(scaffoldBackgroundColor: mobileSearchColor), - home: const SingUpPage(), + home: const LoginPage(), ); } } diff --git a/lib/pages/homepage.dart b/lib/pages/homepage.dart new file mode 100644 index 0000000..d1e698b --- /dev/null +++ b/lib/pages/homepage.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class Homepage extends StatefulWidget { + const Homepage({super.key}); + + @override + State createState() => _HomepageState(); +} + +class _HomepageState extends State { + @override + Widget build(BuildContext context) { + return const Scaffold( + body: Center( + child: Text("this is homepage"), + ), + ); + } +} diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 889ee7c..8027878 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:instagram_clone/service/authentication.dart'; import 'package:instagram_clone/util/colors.dart'; import 'package:instagram_clone/util/text_styles.dart'; import 'package:instagram_clone/util/variabals.dart'; @@ -15,6 +16,9 @@ class LoginPage extends StatefulWidget { class _LoginPageState extends State { final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); + final Authentication _authentication = Authentication(); + bool isLoadding = false; + @override void dispose() { // TODO: implement dispose @@ -23,6 +27,19 @@ class _LoginPageState extends State { super.dispose(); } + void SingInUserAndToggleHome() async { + setState(() { + isLoadding = !isLoadding; + }); + await _authentication.singInUser( + email: _emailController.text, + password: _passwordController.text, + context: context); + setState(() { + isLoadding = !isLoadding; + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -70,8 +87,8 @@ class _LoginPageState extends State { height: 40, ), //login button - GestureDetector( - onTap: () {}, + InkWell( + onTap: SingInUserAndToggleHome, child: Container( width: double.infinity, height: MediaQuery.of(context).size.width * 0.13, @@ -84,7 +101,7 @@ class _LoginPageState extends State { child: Center( child: Text( "Log In", - style: title.copyWith(color: mobileBackgroundColor), + style: title.copyWith(color: primaryColor), ), ), ), diff --git a/lib/pages/sing_up_page.dart b/lib/pages/sing_up_page.dart index 0887134..c90f46d 100644 --- a/lib/pages/sing_up_page.dart +++ b/lib/pages/sing_up_page.dart @@ -1,6 +1,11 @@ +import 'dart:typed_data'; + import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:instagram_clone/service/authentication.dart'; +import 'package:instagram_clone/service/media.dart'; +import 'package:instagram_clone/service/storage.dart'; import 'package:instagram_clone/util/colors.dart'; import 'package:instagram_clone/util/text_styles.dart'; import 'package:instagram_clone/util/variabals.dart'; @@ -18,7 +23,10 @@ class _SingUpPageState extends State { final TextEditingController _passwordController = TextEditingController(); final TextEditingController _usernameController = TextEditingController(); final TextEditingController _bioController = TextEditingController(); - + final Authentication _authServises = Authentication(); + final MediaAdder _adder = MediaAdder(); + Uint8List? _image; + bool isLoading = false; @override void dispose() { // TODO: implement dispose @@ -29,7 +37,32 @@ class _SingUpPageState extends State { super.dispose(); } - Authentication _authServises = Authentication(); + void imageSelector() async { + Uint8List img = await _adder.imagePicker(ImageSource.gallery); + setState(() { + _image = img; + }); + } + + //sing up user:store pro pic and other data + singUpUser() async { + setState(() { + isLoading = !isLoading; + }); + String url = await StorageServices() + .uploadImagesToStorage("profile pics", _image!, false); + await _authServises.singUpUser( + email: _emailController.text, + password: _passwordController.text, + username: _usernameController.text, + bio: _bioController.text, + proPic: url, + context: context); + setState(() { + isLoading = !isLoading; + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -54,16 +87,20 @@ class _SingUpPageState extends State { //add profile pic Stack( children: [ - const CircleAvatar( - radius: 65, - backgroundImage: AssetImage( - "assets/WhatsApp Image 2024-06-03 at 16.37.25_f9a84384.jpg"), - ), + _image != null + ? CircleAvatar( + radius: 65, + backgroundImage: MemoryImage(_image!), + ) + : const CircleAvatar( + radius: 65, + backgroundColor: textboxfillcolor, + ), Positioned( bottom: 0, right: 0, child: IconButton( - onPressed: () {}, + onPressed: imageSelector, icon: const Icon( Icons.add_a_photo, size: 28, @@ -73,7 +110,7 @@ class _SingUpPageState extends State { ) ], ), - SizedBox( + const SizedBox( height: 15, ), //log in form @@ -124,15 +161,8 @@ class _SingUpPageState extends State { height: 40, ), //login button - GestureDetector( - onTap: () async { - _authServises.singUpUser( - email: _emailController.text, - password: _passwordController.text, - username: _usernameController.text, - bio: _bioController.text, - ); - }, + InkWell( + onTap: singUpUser, child: Container( width: double.infinity, height: MediaQuery.of(context).size.width * 0.13, @@ -142,12 +172,17 @@ class _SingUpPageState extends State { borderRadius: BorderRadius.circular(5), ), ), - child: Center( - child: Text( - "Sing Up", - style: title.copyWith(color: primaryColor), - ), - ), + child: !isLoading + ? Center( + child: Text( + "Sing Up", + style: title.copyWith(color: primaryColor), + ), + ) + : const Center( + child: CircularProgressIndicator( + color: primaryColor, + )), ), ), ], diff --git a/lib/service/authentication.dart b/lib/service/authentication.dart index 3d3ab20..1985b38 100644 --- a/lib/service/authentication.dart +++ b/lib/service/authentication.dart @@ -1,19 +1,35 @@ - - import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:instagram_clone/pages/homepage.dart'; +import 'package:instagram_clone/util/colors.dart'; +import 'package:instagram_clone/util/text_styles.dart'; //add firebase auth methods to sing up and sing in users class Authentication { + //instances final FirebaseAuth _auth = FirebaseAuth.instance; final FirebaseFirestore _firestorege = FirebaseFirestore.instance; - Future singUpUser( + + void massage(String res, BuildContext context) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + backgroundColor: textboxfillcolor, + content: Text( + res, + style: body, + ), + ), + ); + } + + Future singUpUser( {required String email, required String password, required String username, required String bio, - // required Uint8List imgfile - }) async { + String proPic = "", + required BuildContext context}) async { try { //create a new user if (email.isNotEmpty && @@ -24,6 +40,9 @@ class Authentication { .createUserWithEmailAndPassword(email: email, password: password); //get created user id final user = userCredential.user!.uid; + + // String url = await _storageServices.uploadImagesToStorage( + // "profile pics", imgfile, false); //store user data await _firestorege.collection("users").doc(user).set({ "uid": user, @@ -31,15 +50,46 @@ class Authentication { "email": email, "password": password, "bio": bio, + "avatar": proPic, "followers": [], "following": [], }); - print("succuss"); + massage("Succsussful Registation", context); + } else { + massage("You have missing data", context); + } + } on FirebaseAuthException catch (err) { + if (err.code == "invalid-email") { + massage("Invalid email format", context); + } else { + massage("Invalid password format", context); + } + } catch (err) { + massage("something went wrong", context); + } + } + + //login user + Future singInUser( + {required String email, + required String password, + required BuildContext context}) async { + // String response = "Invalid username or password"; + try { + if (email.isNotEmpty && password.isNotEmpty) { + await _auth.signInWithEmailAndPassword( + email: email, password: password); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => Homepage(), + )); + // massage("Succsussfuly Log In", context); + } else { + massage("Missing credientials", context); } - print("details missing"); } catch (err) { - print(err.toString()); + massage(err.toString(), context); } - return ""; } } diff --git a/lib/service/media.dart b/lib/service/media.dart new file mode 100644 index 0000000..9276cdf --- /dev/null +++ b/lib/service/media.dart @@ -0,0 +1,13 @@ +import 'package:image_picker/image_picker.dart'; + +class MediaAdder { + Future imagePicker(ImageSource source) async { + final ImagePicker picker = ImagePicker(); + XFile? _image = await picker.pickImage(source: source); + if (_image != null) { + return await _image.readAsBytes(); + } else { + return null; + } + } +} diff --git a/lib/service/storage.dart b/lib/service/storage.dart new file mode 100644 index 0000000..cbc6f3a --- /dev/null +++ b/lib/service/storage.dart @@ -0,0 +1,26 @@ +import 'dart:typed_data'; + +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_storage/firebase_storage.dart'; + +class StorageServices { + final FirebaseStorage _storage = FirebaseStorage.instance; + final FirebaseAuth _auth = FirebaseAuth.instance; + //upload file to storage + Future uploadImagesToStorage( + String folderName, Uint8List file, bool isPost) async { + if (file.isNotEmpty) { + //get the path + Reference reference = + _storage.ref().child(folderName).child(_auth.currentUser!.uid); + //create uploadtask + UploadTask uploadTask = reference.putData(file!); + //get snapshot + TaskSnapshot snapshot = await uploadTask; + //get url of stored image and return + String imageUrl = await snapshot.ref.getDownloadURL(); + return imageUrl; + } + return ""; + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index e71a16d..64a0ece 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); + file_selector_plugin_register_with_registrar(file_selector_linux_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 2e1de87..2db3c22 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + file_selector_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 5348122..2d8b8a3 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import cloud_firestore +import file_selector_macos import firebase_auth import firebase_core import firebase_storage @@ -13,6 +14,7 @@ import path_provider_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) + FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) diff --git a/pubspec.lock b/pubspec.lock index b9fafaa..6977da2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -81,6 +81,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + url: "https://pub.dev" + source: hosted + version: "0.3.4+1" crypto: dependency: transitive description: @@ -113,6 +121,38 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" + url: "https://pub.dev" + source: hosted + version: "0.9.2+1" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 + url: "https://pub.dev" + source: hosted + version: "0.9.4" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69" + url: "https://pub.dev" + source: hosted + version: "0.9.3+2" firebase_auth: dependency: "direct main" description: @@ -198,6 +238,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e + url: "https://pub.dev" + source: hosted + version: "2.0.20" flutter_svg: dependency: "direct main" description: @@ -240,6 +288,70 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: a26dc9a03fe042440c1e4be554fb0fceae2bf6d887d7467fc48c688fa4a81889 + url: "https://pub.dev" + source: hosted + version: "0.8.12+7" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "5d6eb13048cd47b60dbf1a5495424dea226c5faf3950e20bf8120a58efb5b5f3" + url: "https://pub.dev" + source: hosted + version: "3.0.4" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447" + url: "https://pub.dev" + source: hosted + version: "0.8.12" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80" + url: "https://pub.dev" + source: hosted + version: "2.10.0" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" leak_tracker: dependency: transitive description: @@ -296,6 +408,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.12.0" + mime: + dependency: transitive + description: + name: mime + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + url: "https://pub.dev" + source: hosted + version: "1.0.5" path: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 60a41c2..11e0f4d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: cupertino_icons: ^1.0.6 google_fonts: ^6.2.1 flutter_svg: ^2.0.10+1 + image_picker: ^1.1.2 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index ff5147a..ec1e463 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -14,6 +15,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { CloudFirestorePluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); FirebaseAuthPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); FirebaseCorePluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fb0d4f3..767b528 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST cloud_firestore + file_selector_windows firebase_auth firebase_core firebase_storage