tests , readme,file names convention and search companies fix

main
Nadezda Kloos 2023-06-23 12:12:02 +02:00
parent bb8600d2f9
commit e954f240ef
28 changed files with 655 additions and 327 deletions

5
.firebaserc 100644
View File

@ -0,0 +1,5 @@
{
"projects": {
"default": "cpd-last-try"
}
}

View File

@ -1,16 +1,26 @@
# cpd_ss23 ##
## cpd_ss23
A new Flutter project. Sehr geehrter Herr Giess,
Hier ist Job Finder App , entwickelt von 2020633 und 1920881
## Getting Started ## Getting Started
This project is a starting point for a Flutter application. Die von uns entwickelte JobFinder Application verfügt über verschiedene Funktionalitäten, darunter :
Login/Logout,
Account erstellen/ändern,
Job Posten,
Kommentieren
Bewerben/ Kontakt aufnehmen
A few resources to get you started if this is your first Flutter project: Als Backend haben wir uns für Firebase entschieden: wir wollten die Gelegenheit nutzen, um den Umgang und die Integration von Firebase zu lernen.
## Vorgeschlagene Test flow
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 1. Erstellen Sie einene Account. Sie müssen nicht unbedingt ein Bild hochladen. Es wird ein Default Bild zugewiesen.
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 2. Kommentieren/Bewerben Sie sich auf eine offene Jobstelle( zB . n3 Softwareentwickler)
3. Clicken Sie auf Profile eines anderes, der es auch kommentierte
4. Ändern Sie ihren Account
5. Kontaktieren Sie jmd
For help getting started with Flutter development, view the ![img.png](img.png)
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference. Wir haben ein Problem mit dem Bildanzeige in web.

15
firebase.json 100644
View File

@ -0,0 +1,15 @@
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"emulators": {
"functions": {
"port": 5001
},
"ui": {
"enabled": true
},
"singleProjectMode": true
}
}

View File

@ -0,0 +1,51 @@
{
"indexes": [
{
"collectionGroup": "jobs",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "jobCategory",
"order": "ASCENDING"
},
{
"fieldPath": "recruitment",
"order": "ASCENDING"
},
{
"fieldPath": "createdAt",
"order": "ASCENDING"
}
]
},
{
"collectionGroup": "jobs",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "recruitment",
"order": "ASCENDING"
},
{
"fieldPath": "createdAt",
"order": "ASCENDING"
}
]
},
{
"collectionGroup": "jobs",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "recruitment",
"order": "ASCENDING"
},
{
"fieldPath": "jobTitle",
"order": "ASCENDING"
}
]
}
],
"fieldOverrides": []
}

19
firestore.rules 100644
View File

@ -0,0 +1,19 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// This rule allows anyone with your Firestore database reference to view, edit,
// and delete all data in your Firestore database. It is useful for getting
// started, but it is configured to expire after 30 days because it
// leaves your app open to attackers. At that time, all client
// requests to your Firestore database will be denied.
//
// Make sure to write security rules for your app before that time, or else
// all client requests to your Firestore database will be denied until you Update
// your rules
match /{document=**} {
allow read, write: if request.time < timestamp.date(2023, 6, 29);
}
}
}

BIN
img.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -3,7 +3,7 @@ import 'package:firebase_auth/firebase_auth.dart';
import '../services/global_variables.dart'; import '../services/global_variables.dart';
class Persistent{ class Persistent {
static List<String> jobCategoryList = [ static List<String> jobCategoryList = [
"Architecture and Construction", "Architecture and Construction",
"Education and Training", "Education and Training",
@ -16,13 +16,13 @@ class Persistent{
"Accounting" "Accounting"
]; ];
void getMyData() async {
void getMyData() async{ final DocumentSnapshot userDoc = await FirebaseFirestore.instance
final DocumentSnapshot userDoc = await FirebaseFirestore.instance.collection("users").doc(FirebaseAuth.instance.currentUser!.uid) .collection("users")
.doc(FirebaseAuth.instance.currentUser!.uid)
.get(); .get();
name = userDoc.get("name"); name = userDoc.get("name");
userImage = userDoc.get("userImage"); userImage = userDoc.get("userImage");
location = userDoc.get("location"); location = userDoc.get("location");
} }
} }

View File

@ -45,8 +45,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
final Uri params = Uri( final Uri params = Uri(
scheme: "mailto", scheme: "mailto",
path: email, path: email,
query: query: "subject=Hey from JobFinder",
"subject=Hey from JobFinder",
); );
final url = params.toString(); final url = params.toString();
launchUrlString(url); launchUrlString(url);
@ -175,14 +174,13 @@ class _ProfileScreenState extends State<ProfileScreen> {
), ),
), ),
child: Stack( child: Stack(
children: [ children: [
Image.network( Image.network(
signupUrlImage, signupUrlImage,
fit: BoxFit.cover, fit: BoxFit.cover,
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
), ),
SingleChildScrollView( SingleChildScrollView(
child: Column( child: Column(
children: [ children: [

View File

@ -10,7 +10,7 @@ class AllWorkersScreen extends StatefulWidget {
class _AllWorkersScreenState extends State<AllWorkersScreen> { class _AllWorkersScreenState extends State<AllWorkersScreen> {
final TextEditingController _searchQueryController = TextEditingController(); final TextEditingController _searchQueryController = TextEditingController();
String searchQuery = 'Search Query'; String searchQuery = ' ';
Widget _buildSearchField() { Widget _buildSearchField() {
return TextField( return TextField(
@ -60,8 +60,7 @@ class _AllWorkersScreenState extends State<AllWorkersScreen> {
begin: Alignment.centerLeft, begin: Alignment.centerLeft,
end: Alignment.centerRight, end: Alignment.centerRight,
stops: [0.2, 0.9], stops: [0.2, 0.9],
) )),
),
child: Scaffold( child: Scaffold(
bottomNavigationBar: BottomNavigationBarForApp( bottomNavigationBar: BottomNavigationBarForApp(
indexNum: 1, indexNum: 1,

View File

@ -27,8 +27,7 @@ class _AllWorkersWidgetState extends State<AllWorkersWidget> {
final Uri params = Uri( final Uri params = Uri(
scheme: "mailto", scheme: "mailto",
path: widget.userEmail, path: widget.userEmail,
query: query: "subject=Hey from JobFinder",
"subject=Hey from JobFinder",
); );
final url = params.toString(); final url = params.toString();
launchUrlString(url); launchUrlString(url);

View File

@ -9,7 +9,6 @@ import 'package:flutter/material.dart';
import '../jobs/jobs_screen.dart'; import '../jobs/jobs_screen.dart';
class BottomNavigationBarForApp extends StatelessWidget { class BottomNavigationBarForApp extends StatelessWidget {
int indexNum = 0; int indexNum = 0;
BottomNavigationBarForApp({required this.indexNum}); BottomNavigationBarForApp({required this.indexNum});
@ -19,91 +18,113 @@ class BottomNavigationBarForApp extends StatelessWidget {
showDialog( showDialog(
context: context, context: context,
builder: (context){ builder: (context) {
return AlertDialog( return AlertDialog(
backgroundColor: Colors.black54, backgroundColor: Colors.black54,
title: const Row( title: const Row(
children: [ children: [
Padding( Padding(
padding: EdgeInsets.all(8.0), padding: EdgeInsets.all(8.0),
child: Icon( child: Icon(Icons.logout, color: Colors.white, size: 36),
Icons.logout,
color: Colors.white,
size: 36
),
), ),
Padding( Padding(
padding: EdgeInsets.all(8.0), padding: EdgeInsets.all(8.0),
child: Text( child: Text(
"Sign Out", "Sign Out",
style: TextStyle(color: Colors.white, fontSize: 28), style: TextStyle(color: Colors.white, fontSize: 28),
), ),
), ),
], ],
), ),
content: const Text( content: const Text(
"Do you want to Log Out?", "Do you want to Log Out?",
style: TextStyle( style: TextStyle(color: Colors.white, fontSize: 20),
color: Colors.white, fontSize: 20 ),
),
),
actions: [ actions: [
TextButton( TextButton(
onPressed: (){ onPressed: () {
Navigator.canPop(context) ? Navigator.pop(context) : null; Navigator.canPop(context) ? Navigator.pop(context) : null;
}, },
child: const Text("No", style: TextStyle(color: Colors.green, fontSize: 18),), child: const Text(
"No",
style: TextStyle(color: Colors.green, fontSize: 18),
),
), ),
TextButton( TextButton(
onPressed: (){ onPressed: () {
_auth.signOut(); _auth.signOut();
Navigator.canPop(context) ? Navigator.pop(context) : null; Navigator.canPop(context) ? Navigator.pop(context) : null;
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => UserState())); Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => UserState()));
}, },
child: const Text("Yes", style: TextStyle(color: Colors.green, fontSize: 18),), child: const Text(
"Yes",
style: TextStyle(color: Colors.green, fontSize: 18),
),
) )
], ],
); );
} });
);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CurvedNavigationBar( return CurvedNavigationBar(
color: Colors.cyan, color: Colors.cyan,
backgroundColor: Colors.black, backgroundColor: Colors.black,
buttonBackgroundColor: Colors.white, buttonBackgroundColor: Colors.white,
height: 50, height: 50,
index: indexNum, index: indexNum,
items: const [ items: const [
Icon(Icons.list, size: 19, color: Colors.black,), Icon(
Icon(Icons.search, size: 19, color: Colors.black,), Icons.list,
Icon(Icons.add, size: 19, color: Colors.black,), size: 19,
Icon(Icons.person_pin, size: 19, color: Colors.black,), color: Colors.black,
Icon(Icons.exit_to_app, size: 19, color: Colors.black,), ),
], Icon(
Icons.search,
size: 19,
color: Colors.black,
),
Icon(
Icons.add,
size: 19,
color: Colors.black,
),
Icon(
Icons.person_pin,
size: 19,
color: Colors.black,
),
Icon(
Icons.exit_to_app,
size: 19,
color: Colors.black,
),
],
animationDuration: const Duration( animationDuration: const Duration(
milliseconds: 300, milliseconds: 300,
), ),
animationCurve: Curves.bounceInOut, animationCurve: Curves.bounceInOut,
onTap: (index){ onTap: (index) {
if(index == 0){ if (index == 0) {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => JobScreen())); Navigator.pushReplacement(
} else if (index == 1){ context, MaterialPageRoute(builder: (_) => JobScreen()));
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => AllWorkersScreen())); } else if (index == 1) {
} else if (index == 2){ Navigator.pushReplacement(
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => UploadJobNow())); context, MaterialPageRoute(builder: (_) => AllWorkersScreen()));
} else if (index == 3){ } else if (index == 2) {
final FirebaseAuth _auth = FirebaseAuth.instance; Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => UploadJobNow()));
} else if (index == 3) {
final FirebaseAuth _auth = FirebaseAuth.instance;
final User? user = _auth.currentUser; final User? user = _auth.currentUser;
final String uid = user!.uid; final String uid = user!.uid;
Navigator.pushReplacement(context, Navigator.pushReplacement(context,
MaterialPageRoute(builder: (_) => ProfileScreen(userID: uid))); MaterialPageRoute(builder: (_) => ProfileScreen(userID: uid)));
} else if (index == 4) {
_logout(context);
} }
else if (index == 4){
_logout(context);
}
}, },
); );
} }

View File

@ -46,19 +46,30 @@ class _JobWidgetState extends State<JobWidget> {
return AlertDialog( return AlertDialog(
actions: [ actions: [
TextButton( TextButton(
onPressed: () async{ onPressed: () async {
try{ try {
if(widget.uploadedBy == _uid){ if (widget.uploadedBy == _uid) {
await FirebaseFirestore.instance.collection("jobs").doc(widget.jobId).delete(); await FirebaseFirestore.instance
await Fluttertoast.showToast(msg: "Job has been deleted", toastLength: Toast.LENGTH_LONG, backgroundColor: Colors.grey, fontSize: 18.0); .collection("jobs")
Navigator.canPop(context) ? Navigator.pop(context) : null; .doc(widget.jobId)
.delete();
await Fluttertoast.showToast(
msg: "Job has been deleted",
toastLength: Toast.LENGTH_LONG,
backgroundColor: Colors.grey,
fontSize: 18.0);
Navigator.canPop(context)
? Navigator.pop(context)
: null;
} else { } else {
GlobalMethod.showErrorDialog(error: "You cannot perform this action!", ctx: ctx); GlobalMethod.showErrorDialog(
error: "You cannot perform this action!", ctx: ctx);
} }
} catch (error){ } catch (error) {
//TODO Error kommt immer beim löschen fon Job aber funktioniert trotzdem //TODO Error kommt immer beim löschen fon Job aber funktioniert trotzdem
GlobalMethod.showErrorDialog(error: "This task cannot be deleted", ctx: ctx); GlobalMethod.showErrorDialog(
} finally{} error: "This task cannot be deleted", ctx: ctx);
} finally {}
}, },
child: const Row( child: const Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,

View File

@ -43,7 +43,8 @@ class ForgetPasswort extends StatelessWidget {
), ),
Center( Center(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 80), padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 80),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,

View File

@ -102,7 +102,7 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> {
} }
applyForJob() { applyForJob() {
final Uri params = Uri( final Uri params = Uri(
scheme: "mailto", scheme: "mailto",
path: emailCompany, path: emailCompany,
query: "subject=Hey from JobFinder", query: "subject=Hey from JobFinder",
@ -539,33 +539,55 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> {
horizontal: 8), horizontal: 8),
child: MaterialButton( child: MaterialButton(
onPressed: () async { onPressed: () async {
if(_commentController.text.length < 7){ if (_commentController
GlobalMethod.showErrorDialog(error: "Komment > 7 chars", ctx: context); .text.length <
} 7) {
else{ GlobalMethod.showErrorDialog(
final _generatedId= Uuid().v4(); error:
await FirebaseFirestore.instance.collection('jobs').doc(widget.jobID).update({ "Komment > 7 chars",
'jobComments': ctx: context);
FieldValue.arrayUnion([ } else {
{'userId':FirebaseAuth.instance.currentUser!.uid, final _generatedId =
'commentId':_generatedId, Uuid().v4();
'name': name, await FirebaseFirestore
'userImage':userImage, .instance
'commentBody': _commentController.text, .collection('jobs')
'time': Timestamp.now(),} .doc(widget.jobID)
.update({
'jobComments': FieldValue
.arrayUnion([
{
'userId': FirebaseAuth
.instance
.currentUser!
.uid,
'commentId':
_generatedId,
'name': name,
'userImage':
userImage,
'commentBody':
_commentController
.text,
'time':
Timestamp.now(),
}
]) ])
}); });
await Fluttertoast.showToast( await Fluttertoast
msg: 'Kommentaar wurde uploaded', .showToast(
toastLength: Toast.LENGTH_LONG, msg:
backgroundColor: Colors.grey, 'Kommentaar wurde uploaded',
toastLength:
Toast.LENGTH_LONG,
backgroundColor:
Colors.grey,
fontSize: 18.0, fontSize: 18.0,
); );
_commentController.clear(); _commentController.clear();
setState(() { setState(() {
showComment = true; showComment = true;
}); });
} }
}, },
color: Colors.blueAccent, color: Colors.blueAccent,
@ -587,11 +609,10 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> {
TextButton( TextButton(
onPressed: () { onPressed: () {
setState(() { setState(() {
_isCommenting=!_isCommenting; _isCommenting =
!_isCommenting;
showComment = false; showComment = false;
}); });
}, },
child: const Text("Cancel"), child: const Text("Cancel"),
) )
@ -606,9 +627,8 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> {
IconButton( IconButton(
onPressed: () { onPressed: () {
setState(() { setState(() {
_isCommenting=!_isCommenting; _isCommenting = !_isCommenting;
}); });
}, },
icon: const Icon( icon: const Icon(
Icons.add_comment, Icons.add_comment,
@ -621,7 +641,6 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> {
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
setState(() { setState(() {
showComment = true; showComment = true;
}); });
@ -634,47 +653,61 @@ class _JobDetailsScreenState extends State<JobDetailsScreen> {
), ),
], ],
)), )),
showComment == false ? showComment == false
Container() ? Container()
: Padding( : Padding(
padding:EdgeInsets.all(16.0), padding: EdgeInsets.all(16.0),
child: FutureBuilder<DocumentSnapshot>( child: FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance.collection('jobs').doc(widget.jobID).get(), future: FirebaseFirestore.instance
builder:(context,snapshot){ .collection('jobs')
if(snapshot.connectionState == ConnectionState.waiting){ .doc(widget.jobID)
return const Center(child:CircularProgressIndicator(),); .get(),
} builder: (context, snapshot) {
else { if (snapshot.connectionState ==
if(snapshot.data == null){ ConnectionState.waiting) {
return const Center(child:Text("Keine kommentare"),); return const Center(
} child: CircularProgressIndicator(),
);
} } else {
return ListView.separated( if (snapshot.data == null) {
shrinkWrap: true, return const Center(
physics: const NeverScrollableScrollPhysics(), child: Text("Keine kommentare"),
itemBuilder: (context, index) { );
return CommentWidget( }
commentId: snapshot.data!['jobComments'][index]['commentId'], }
commenterId: snapshot.data!['jobComments'][index]['userId'], return ListView.separated(
commentBody: snapshot.data!['jobComments'][index]['commentBody'], shrinkWrap: true,
commenterImageUrl: snapshot.data!['jobComments'][index]['userImage'], physics:
commenterName: snapshot.data!['jobComments'][index]['name'], const NeverScrollableScrollPhysics(),
); itemBuilder: (context, index) {
}, return CommentWidget(
separatorBuilder: (context, index) { commentId:
return const Divider( snapshot.data!['jobComments']
thickness: 1, [index]['commentId'],
color: Colors.grey, commenterId:
); snapshot.data!['jobComments']
}, [index]['userId'],
itemCount: snapshot.data!['jobComments'].length, commentBody:
); snapshot.data!['jobComments']
[index]['commentBody'],
commenterImageUrl:
} snapshot.data!['jobComments']
) [index]['userImage'],
) commenterName:
snapshot.data!['jobComments']
[index]['name'],
);
},
separatorBuilder: (context, index) {
return const Divider(
thickness: 1,
color: Colors.grey,
);
},
itemCount: snapshot
.data!['jobComments'].length,
);
}))
], ],
), ),
), ),

View File

@ -42,7 +42,8 @@ class _JobScreenState extends State<JobScreen> {
jobCategoryFilter = Persistent.jobCategoryList[index]; jobCategoryFilter = Persistent.jobCategoryList[index];
}); });
Navigator.canPop(context) ? Navigator.pop(context) : null; Navigator.canPop(context) ? Navigator.pop(context) : null;
print("jobCategoryList[index], ${Persistent.jobCategoryList[index]}"); print(
"jobCategoryList[index], ${Persistent.jobCategoryList[index]}");
}, },
child: Row( child: Row(
children: [ children: [
@ -157,7 +158,8 @@ class _JobScreenState extends State<JobScreen> {
.orderBy("createdAt", descending: false) .orderBy("createdAt", descending: false)
.snapshots(), .snapshots(),
builder: (context, AsyncSnapshot snapshot) { builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) { if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center( return const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
); );
@ -169,15 +171,21 @@ class _JobScreenState extends State<JobScreen> {
itemCount: snapshot.data?.docs.length, itemCount: snapshot.data?.docs.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return JobWidget( return JobWidget(
jobTitle: snapshot.data?.docs[index]["jobTitle"], jobTitle: snapshot.data?.docs[index]
jobDescription: snapshot.data!.docs[index]["jobDescription"], ["jobTitle"],
jobDescription: snapshot.data!.docs[index]
["jobDescription"],
jobId: snapshot.data?.docs[index]["jobId"], jobId: snapshot.data?.docs[index]["jobId"],
uploadedBy: snapshot.data?.docs[index]["uploadedBy"], uploadedBy: snapshot.data?.docs[index]
userImage: snapshot.data?.docs[index]["userImage"], ["uploadedBy"],
userImage: snapshot.data?.docs[index]
["userImage"],
name: snapshot.data?.docs[index]["name"], name: snapshot.data?.docs[index]["name"],
recruitment: snapshot.data?.docs[index]["recruitment"], recruitment: snapshot.data?.docs[index]
["recruitment"],
email: snapshot.data?.docs[index]["email"], email: snapshot.data?.docs[index]["email"],
location: snapshot.data?.docs[index]["location"], location: snapshot.data?.docs[index]
["location"],
); );
}, },
); );
@ -200,7 +208,6 @@ class _JobScreenState extends State<JobScreen> {
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
), ),
), ),

View File

@ -31,7 +31,7 @@ class _UploadJobNowState extends State<UploadJobNow> {
bool _isLoading = false; bool _isLoading = false;
@override @override
void dispose(){ void dispose() {
super.dispose(); super.dispose();
_jobCategoryController.dispose(); _jobCategoryController.dispose();
_jobTitleController.dispose(); _jobTitleController.dispose();
@ -242,9 +242,6 @@ class _UploadJobNowState extends State<UploadJobNow> {
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;

View File

@ -4,8 +4,6 @@ import 'package:cpd_ss23/services/global_methods.dart';
import 'package:cpd_ss23/services/global_variables.dart'; import 'package:cpd_ss23/services/global_variables.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../forget_passwort/forget_pass_screen.dart';
import '../signup_page/signup_screen.dart'; import '../signup_page/signup_screen.dart';
class Login extends StatefulWidget { class Login extends StatefulWidget {

View File

@ -1,37 +1,15 @@
import 'package:cpd_ss23/login_page/login_screen.dart';
import 'package:cpd_ss23/test.dart';
import 'package:cpd_ss23/user_state.dart'; import 'package:cpd_ss23/user_state.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:cpd_ss23/firebase_options.dart'; // Importieren Sie die Firebase-Optionen import 'package:cpd_ss23/firebase_options.dart'; // Importieren Sie die Firebase-Optionen
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart'; void main() async {
void main() async {/*
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase Test',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FirebaseTestPage(),
);
}
}*/
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp()); runApp(MyApp());
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
final Future<FirebaseApp> _initialisation = Firebase.initializeApp(); final Future<FirebaseApp> _initialisation = Firebase.initializeApp();
@ -89,4 +67,3 @@ class MyApp extends StatelessWidget {
); );
} }
} }

View File

@ -2,14 +2,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class GlobalMethod{ class GlobalMethod {
static void showErrorDialog({required String error, required BuildContext ctx}) { static void showErrorDialog(
{required String error, required BuildContext ctx}) {
showDialog( showDialog(
context: ctx, context: ctx,
builder: (context) { builder: (context) {
return AlertDialog( return AlertDialog(
title: Row ( title: Row(
children: const [ children: const [
Padding( Padding(
padding: EdgeInsets.all(8.0), padding: EdgeInsets.all(8.0),
child: Icon(Icons.logout, color: Colors.grey, size: 35), child: Icon(Icons.logout, color: Colors.grey, size: 35),
@ -31,8 +32,9 @@ class GlobalMethod{
actions: [ actions: [
TextButton( TextButton(
onPressed: () { onPressed: () {
Navigator.canPop(context) ? Navigator.pop(context) : null; // Zurücknavigieren, falls möglich Navigator.canPop(context)
? Navigator.pop(context)
: null; // Zurücknavigieren, falls möglich
}, },
child: const Text( child: const Text(
'oki doki', 'oki doki',
@ -44,7 +46,6 @@ class GlobalMethod{
}, },
); );
} }
static void getPicture(){
} static void getPicture() {}
} }

View File

@ -1,6 +1,9 @@
String loginUrlImage = "https://images.unsplash.com/photo-1523050854058-8df90110c9f1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8dW5pdmVyc2l0eXxlbnwwfHwwfHw%3D&w=1000&q=80"; String loginUrlImage =
String signupUrlImage= 'https://images.unsplash.com/photo-1575330734740-21b22ac7bf5e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxleHBsb3JlLWZlZWR8MXx8fGVufDB8fHx8fA%3D%3D&w=1000&q=80'; "https://images.unsplash.com/photo-1523050854058-8df90110c9f1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8dW5pdmVyc2l0eXxlbnwwfHwwfHw%3D&w=1000&q=80";
String signupGenericImage = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSeqUFP0nU4pUnNncq4dy7M6X6xYRYwUQduFcLkQ9yEAYMzORlw5eHddyCPMUY4yK2PBJ8&usqp=CAU'; String signupUrlImage =
'https://images.unsplash.com/photo-1575330734740-21b22ac7bf5e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxleHBsb3JlLWZlZWR8MXx8fGVufDB8fHx8fA%3D%3D&w=1000&q=80';
String signupGenericImage =
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSeqUFP0nU4pUnNncq4dy7M6X6xYRYwUQduFcLkQ9yEAYMzORlw5eHddyCPMUY4yK2PBJ8&usqp=CAU';
String? name = ""; String? name = "";
String? userImage = ""; String? userImage = "";
String? location = ""; String? location = "";

View File

@ -12,8 +12,6 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/foundation.dart' show kIsWeb;
class SignUp extends StatefulWidget { class SignUp extends StatefulWidget {
@override @override
State<SignUp> createState() => _SignUpState(); State<SignUp> createState() => _SignUpState();
@ -27,7 +25,8 @@ class _SignUpState extends State<SignUp> {
final TextEditingController _nameTextController = TextEditingController(); final TextEditingController _nameTextController = TextEditingController();
final TextEditingController _cityTextController = TextEditingController(); final TextEditingController _cityTextController = TextEditingController();
final TextEditingController _emailTextController = TextEditingController(); final TextEditingController _emailTextController = TextEditingController();
final TextEditingController _phoneNumberTextController = TextEditingController(); final TextEditingController _phoneNumberTextController =
TextEditingController();
final TextEditingController _passwordTextController = TextEditingController(); final TextEditingController _passwordTextController = TextEditingController();
bool _isLoading = false; bool _isLoading = false;
final FirebaseAuth _auth = FirebaseAuth.instance; final FirebaseAuth _auth = FirebaseAuth.instance;
@ -71,18 +70,18 @@ class _SignUpState extends State<SignUp> {
void _submitFormSignup() async { void _submitFormSignup() async {
final isValid = _signUpFormKey.currentState!.validate(); final isValid = _signUpFormKey.currentState!.validate();
if (isValid) { if (isValid) {
if (imageFile == null) { if (imageFile == null) {
if (kIsWeb) { if (kIsWeb) {
//hier sollte eine methode zum erstellen des Files aus internet geben( weil in web path_provider.dart'; nicht realoisiert ist) , aber es ist mir zu viel //hier sollte eine methode zum erstellen des Files aus internet geben( weil in web path_provider.dart'; nicht realoisiert ist) , aber es ist mir zu viel
} else { } else {
final appDir = await getApplicationDocumentsDirectory(); final appDir = await getApplicationDocumentsDirectory();
final defaultImagePath = '${appDir.path}/default_profile_image.jpg'; final defaultImagePath = '${appDir.path}/default_profile_image.jpg';
final defaultImageAsset = await rootBundle.load( final defaultImageAsset =
'assets/images/genericProfile.jpg'); await rootBundle.load('assets/images/genericProfile.jpg');
final bytes = defaultImageAsset.buffer.asUint8List(); final bytes = defaultImageAsset.buffer.asUint8List();
await File(defaultImagePath).writeAsBytes(bytes); await File(defaultImagePath).writeAsBytes(bytes);
imageFile = File(defaultImagePath); imageFile = File(defaultImagePath);
} }
} }
} }
setState(() { setState(() {
@ -90,36 +89,40 @@ class _SignUpState extends State<SignUp> {
}); });
try { try {
await _auth.createUserWithEmailAndPassword( await _auth.createUserWithEmailAndPassword(
email: _emailTextController.text.trim(), email: _emailTextController.text.trim(),
password: _passwordTextController.text.trim(), password: _passwordTextController.text.trim(),
); );
final User? user = _auth.currentUser; final User? user = _auth.currentUser;
final _uid = user!.uid; final _uid = user!.uid;
if (kIsWeb) { if (kIsWeb) {
imageUrl= "https://firebasestorage.googleapis.com/v0/b/cpd-last-try.appspot.com/o/userImages%2Fweb_foto.jpeg?alt=media&token=41db34c9-ce68-4d5f-a10b-e45802479999"; imageUrl =
} "https://firebasestorage.googleapis.com/v0/b/cpd-last-try.appspot.com/o/userImages%2Fweb_foto.jpeg?alt=media&token=41db34c9-ce68-4d5f-a10b-e45802479999";
else{ } else {
final ref = FirebaseStorage.instance.ref().child('userImages').child('$_uid.jpg'); final ref = FirebaseStorage.instance
await ref.putFile(imageFile!); .ref()
imageUrl = await ref.getDownloadURL();} .child('userImages')
FirebaseFirestore.instance.collection('users').doc(_uid).set({ .child('$_uid.jpg');
'id': _uid, await ref.putFile(imageFile!);
'name': _nameTextController.text, imageUrl = await ref.getDownloadURL();
'email': _emailTextController.text, }
'userImage':imageUrl, FirebaseFirestore.instance.collection('users').doc(_uid).set({
'phone':_phoneNumberTextController.text, 'id': _uid,
'location': _cityTextController.text, 'name': _nameTextController.text,
'createdAt': Timestamp.now(), 'email': _emailTextController.text,
'userImage': imageUrl,
}); 'phone': _phoneNumberTextController.text,
Navigator.canPop(context) ? Navigator.pop(context) : null; 'location': _cityTextController.text,
} catch (e) { 'createdAt': Timestamp.now(),
});
Navigator.canPop(context) ? Navigator.pop(context) : null;
} catch (e) {
// Handle any errors that occur during sign-up // Handle any errors that occur during sign-up
setState(){ setState() {
_isLoading = false; _isLoading = false;
} }
GlobalMethod.showErrorDialog(error: e.toString(), ctx: context);
GlobalMethod.showErrorDialog(error: e.toString(), ctx: context);
} }
setState(() { setState(() {
_isLoading = false; _isLoading = false;
@ -146,7 +149,8 @@ class _SignUpState extends State<SignUp> {
children: [ children: [
Form( Form(
key: _signUpFormKey, key: _signUpFormKey,
autovalidateMode: AutovalidateMode.always, // Enable immediate validation autovalidateMode:
AutovalidateMode.always, // Enable immediate validation
child: Column( child: Column(
children: [ children: [
GestureDetector( GestureDetector(
@ -163,21 +167,22 @@ class _SignUpState extends State<SignUp> {
width: size.width * 0.44, width: size.width * 0.44,
height: size.width * 0.44, height: size.width * 0.44,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(width: 5, color: Colors.cyan), border:
Border.all(width: 5, color: Colors.cyan),
borderRadius: BorderRadius.circular(100), borderRadius: BorderRadius.circular(100),
), ),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(100), borderRadius: BorderRadius.circular(100),
child: imageFile == null child: imageFile == null
? const Icon( ? const Icon(
Icons.camera_alt_rounded, Icons.camera_alt_rounded,
color: Colors.cyan, color: Colors.cyan,
size: 120, size: 120,
) )
: Image.file( : Image.file(
imageFile!, imageFile!,
fit: BoxFit.fill, fit: BoxFit.fill,
), ),
), ),
), ),
), ),
@ -241,32 +246,33 @@ class _SignUpState extends State<SignUp> {
), ),
_isLoading _isLoading
? Center( ? Center(
child: Container( child: Container(
width: 70, width: 70,
height: 70, height: 70,
child: const CircularProgressIndicator(), child: const CircularProgressIndicator(),
),
)
: MaterialButton(
onPressed: _submitFormSignup, color: Colors.cyan,
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13)),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 14),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Sign Up',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
), ),
], )
), : MaterialButton(
), onPressed: _submitFormSignup,
), color: Colors.cyan,
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(13)),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 14),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Sign Up',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
],
),
),
),
const SizedBox( const SizedBox(
height: 15, height: 15,
), ),

View File

@ -33,8 +33,10 @@ class _FirebaseTestPageState extends State<FirebaseTestPage> {
Future<void> testFirebaseAuth() async { Future<void> testFirebaseAuth() async {
try { try {
UserCredential userCredential = await FirebaseAuth.instance.signInAnonymously(); UserCredential userCredential =
print('Firebase Authentication Successful. User ID: ${userCredential.user?.uid}'); await FirebaseAuth.instance.signInAnonymously();
print(
'Firebase Authentication Successful. User ID: ${userCredential.user?.uid}');
} catch (e) { } catch (e) {
print('Firebase Authentication Error: $e'); print('Firebase Authentication Error: $e');
} }

View File

@ -5,40 +5,36 @@ import 'package:flutter/material.dart';
import 'login_page/login_screen.dart'; import 'login_page/login_screen.dart';
class UserState extends StatelessWidget {// enthält keine internen Variablen, die sich während der Laufzeit ändern können. class UserState extends StatelessWidget {
// enthält keine internen Variablen, die sich während der Laufzeit ändern können.
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StreamBuilder( return StreamBuilder(
stream:FirebaseAuth.instance.authStateChanges(),builder: (context, userSnapshot){ stream: FirebaseAuth.instance.authStateChanges(),
if(userSnapshot.data == null){ builder: (context, userSnapshot) {
if (userSnapshot.data == null) {
print('user isnt logged in yet'); print('user isnt logged in yet');
return Login(); return Login();
} } else if (userSnapshot.hasData) {
else if(userSnapshot.hasData){
print('user is already logged in '); print('user is already logged in ');
return JobScreen(); return JobScreen();
} } else if (userSnapshot.hasError) {
else if(userSnapshot.hasError){
return const Scaffold(
body: Center(
child:Text("An Error ossured"),
)
);
}
else if(userSnapshot.connectionState == ConnectionState.waiting){
return const Scaffold( return const Scaffold(
body: Center( body: Center(
child:CircularProgressIndicator(), child: Text("An Error ossured"),
) ));
); } else if (userSnapshot.connectionState == ConnectionState.waiting) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
));
} }
return const Scaffold(body:Center( return const Scaffold(
child:Text( "Smt went wrong"), body: Center(
child: Text("Smt went wrong"),
)); ));
}, },
); );
} }
} }

View File

@ -1,6 +1,14 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a
url: "https://pub.dev"
source: hosted
version: "61.0.0"
_flutterfire_internals: _flutterfire_internals:
dependency: transitive dependency: transitive
description: description:
@ -9,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.3" version: "1.3.3"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562
url: "https://pub.dev"
source: hosted
version: "5.13.0"
archive: archive:
dependency: transitive dependency: transitive
description: description:
@ -17,6 +33,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.7" version: "3.3.7"
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -33,6 +57,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
build:
dependency: transitive
description:
name: build
sha256: "43865b79fbb78532e4bff7c33087aa43b1d488c4fdef014eaef568af6d8016dc"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166"
url: "https://pub.dev"
source: hosted
version: "8.6.1"
cached_network_image: cached_network_image:
dependency: "direct main" dependency: "direct main"
description: description:
@ -97,6 +145,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.6.1" version: "3.6.1"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189"
url: "https://pub.dev"
source: hosted
version: "4.5.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -145,6 +201,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.3" version: "1.0.3"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad
url: "https://pub.dev"
source: hosted
version: "2.3.1"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -273,6 +337,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.6.3" version: "3.6.3"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -336,6 +408,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.2.2" version: "8.2.2"
glob:
dependency: transitive
description:
name: glob
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@ -396,10 +476,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: image_picker_android name: image_picker_android
sha256: "216dbfb6609e46f78613b8913d046a162588ad4f34909ae7bf85e9f94ea6d922" sha256: d2bab152deb2547ea6f53d82ebca9b7e77386bb706e5789e815d37e08ea475bb
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.7" version: "0.8.7+3"
image_picker_for_web: image_picker_for_web:
dependency: transitive dependency: transitive
description: description:
@ -472,6 +552,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "2.0.1"
logging:
dependency: transitive
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -504,6 +592,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
mockito:
dependency: "direct dev"
description:
name: mockito
sha256: dd61809f04da1838a680926de50a9e87385c1de91c6579629c3d1723946e8059
url: "https://pub.dev"
source: hosted
version: "5.4.0"
octo_image: octo_image:
dependency: transitive dependency: transitive
description: description:
@ -512,6 +608,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
package_config:
dependency: transitive
description:
name: package_config
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -616,6 +720,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2.4" version: "4.2.4"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
@ -629,6 +741,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33"
url: "https://pub.dev"
source: hosted
version: "1.3.2"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@ -789,6 +909,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
watcher:
dependency: transitive
description:
name: watcher
sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
win32: win32:
dependency: transitive dependency: transitive
description: description:
@ -813,6 +941,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.0" version: "6.3.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks: sdks:
dart: ">=3.0.0-378.0.dev <4.0.0" dart: ">=3.0.0-378.0.dev <4.0.0"
flutter: ">=3.3.0" flutter: ">=3.3.0"

View File

@ -33,6 +33,7 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
mockito: ^5.0.0
flutter_lints: ^2.0.0 flutter_lints: ^2.0.0
@ -42,6 +43,7 @@ flutter:
assets: assets:
- assets/images/ - assets/images/
- test/google-services-test.json
fonts: fonts:
- family: Signatra - family: Signatra

View File

@ -0,0 +1,13 @@
{
"type": "service_account",
"project_id": "cpd-last-try",
"private_key_id": "a574c92606dc877fec4fa860e1584120a097fa99",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCY/QbjHoU1i1qj\n2nOjJoBEw8SkoDp4g5iXoohAlsRwDJkSpA5xPeJhQ1V/R29bZUC1vqlTeSWt2AvV\n0TmZnObqRKcP0yzFwuZI8hgE17Excwc90lQDbEgku9ZsiryYvCzI2iFJyV/gjzd6\nJB4Hd7FFxwFmF4Dh2qhD4XcY6WwQkNFY73yLbUAZUkL3mfb36sbDR28KX04Z32TQ\n+Lq8FqbAuq9TotpvkInjspdu1OYkDuc9XQezSulAz7zcOmz9fLFBsrJSojx2ppK8\nRPUuckIJPLAec0jeGT6IfLiODXPxwmTuSSPc51Yx1of7qY1gnEGR64f20eiXY6C0\nMLFESuA7AgMBAAECggEABGbn+9NHRoVr+IZpv6pQgfMpPC7W7ZMSoO7lbwieYu1D\nA20nT4P6nUQeJjtlrXAertLrUOuNvpCERqmTE0hywQ90EWvtiUxUoa3VmfKj/7g/\nljxd6ekDs4rhzAJNXTMfMjFv/zHObiVnp9CdqAJ+OZhU3WaUTH2lAvOS+/2pIKMj\nQpGLtUqI2+zm49u/EIGx/OHJLM0ivjLfIW94sdqmEQrCaQpC2SEG5vIxKwnOtyvw\nYoZ4Rbb4qx8cPJ6A8RTqmw38TzXiLZL4YauvIiRDcsGeu/3QY9Donk7FaMxCXcQD\nMnPqFmXq9THPyo7xU+3pZGwRmAM1Wqyndn0W0Yw/gQKBgQDTAEaiTkMt/AnXZnoa\noYOIq7uKEwROcZ1+JGjNjboj+2QfSCBBACdIgfCrP+2Q/2DQNPlemUEz8T5JGsK4\n8+58sjaW/dqsXXsyzcMAm/ID+cOd/iMHE0iBWa1Jz7+7zdOi9CqFWxDMdOtcYjrk\n6/O9WU7ErO/4rdxLYfYRORDOrQKBgQC5nYPZnv5CQ+jGYekpLkVkJGCPg6/F9CPa\nm69xgCNFS5ZTpAKxLbiwUaDcHPeyGeytHhxgY19C1c3kqknMm4iVsHOo5lMCwFgu\nRhTuCm/36O2K2RoiimgHwxAXc5q12TbteP+/jQIbUCFqxfo7dbFCHryHKAc4gBAy\nc28fJJDPhwKBgBnc4cuJLkDXsNkfLX5QJ9A7xIwDErcOxBAvJE11vsgkSzxuWc29\n2BLSIo7LEjKAqvw6UgqfXFeijVDmn9GNzMCqE3jkesY/2xb6E5nig4KrPagC+4Yl\nffCk7lGqzkSV0QgbR476/48gEa1MOQ3QQhsGdFo1HGDt5p+yzTeFOCMtAoGBAKiB\nfvlJhbnSvLecm3dvMj+/ZonjGueyw/np7FQ1588417gG5QrEXy5ybH5nLdbaAisH\ncutuS0T5pHk6vtSpPk3mapmivyl4RJV9ufKANzXwl/W9MiS5Ucf6JdmkcYc1MtBT\nUJotAQSasjukj477QXitPqnUhPmeCRZEBVVYdL5xAoGAX7xuakEjjzOtRfz1U57p\nhtoD8CzPQYuT5Tq2HSTiKhi7WB5HQPOGoKLw+oq7HZxAun/sZ0wbZZj3uvEX6FDJ\n7Ail+qibInlp1VtPlwbXRT7kB0b4fGNEONd75YHWeCagHuU7VFGh2FPnbmFN4XU/\nyxxRe2fJ62GzrO7WcwSeyM8=\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-fi8et@cpd-last-try.iam.gserviceaccount.com",
"client_id": "103781669883338209830",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fi8et%40cpd-last-try.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}

22
test/mock.dart 100644
View File

@ -0,0 +1,22 @@
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
typedef Callback = void Function(MethodCall call);
void setupFirebaseAuthMocks([Callback? customHandlers]) {
TestWidgetsFlutterBinding.ensureInitialized();
setupFirebaseCoreMocks();
}
Future<T> neverEndingFuture<T>() async {
// ignore: literal_only_boolean_expressions
while (true) {
await Future.delayed(const Duration(minutes: 5));
}
}

View File

@ -1,30 +1,36 @@
// This is a basic Flutter widget test. import 'package:cpd_ss23/jobs/jobs_screen.dart';
// import 'package:cpd_ss23/login_page/login_screen.dart';
// To perform an interaction with a widget in your test, use the WidgetTester import 'package:cpd_ss23/user_state.dart';
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cpd_ss23/main.dart'; import './mock.dart';
void main() { void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async { setupFirebaseAuthMocks();
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that our counter starts at 0. setUpAll(() async {
expect(find.text('0'), findsOneWidget); await Firebase.initializeApp();
expect(find.text('1'), findsNothing); });
// Tap the '+' icon and trigger a frame. testWidgets('Firebase Initialization Test', (WidgetTester tester) async {
await tester.tap(find.byIcon(Icons.add)); // Initialize Firebase
await tester.pump();
// Verify that our counter has incremented. // Check if Firebase is initialized
expect(find.text('0'), findsNothing); final isFirebaseInitialized = Firebase.apps.isNotEmpty;
expect(find.text('1'), findsOneWidget);
// Perform your test assertions
expect(isFirebaseInitialized, isTrue);
});
testWidgets('UserState Widget - User not logged in',
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(home: UserState()));
// Überprüfen, ob das Login-Widget angezeigt wird
expect(find.byType(Login), findsOneWidget);
// Überprüfen, ob das JobScreen-Widget nicht angezeigt wird
expect(find.byType(JobScreen), findsNothing);
}); });
} }