Download as pdf or txt
Download as pdf or txt
You are on page 1of 131

Kingdome of Saudi Arabia

Ministry of Higher Education ٍٍُ‫صاسج اٌرع‬ٚ - ‫دٌح‬ٛ‫اٌٍّّىح اٌعشتٍح اٌسع‬


Princess Nora Bint Abdul Rahman University ّٓ‫سج تٕد عثذ اٌشح‬ٛٔ ‫ظاِعح األٍِشج‬
Faculty of Computer & Information Science ‫ِاخ‬ٍٛ‫اٌّع‬ٚ ‫َ اٌحاسة‬ٍٛ‫وٍٍح ع‬
Graduation Project II 2 ‫ع ذخشض‬ٚ‫ِشش‬

GEO-LOCALIZATION OF LOST
CHILDREN USING IOT
Graduation Project
Report, Part – 2
Submitted for the fulfillment of
bachelor’s degree requirements

Information Technology
CCIS, PNU
Riyadh, KSA
2021 – 2022
Submitted by:

Leena Mohammed Al-Menabhi 438003373


Latifa Fahad Al-Shayea 438007132
Fatimah Saeed Al-Mousa 438003913
Renad Majed Basulayman 438003537
Ghaida Abdulrauf Ababtain 438004293
Areej Attallah Al-Mutrfy 436006977

Supervised by: Dr. Manel Ayadi

Section: 8W4 - 14188

2|Page
Table of Content
Acknowledgment ____________________________________ 3
Abstract ___________________________________________ 3
Keyword __________________________________________ 3
Chapter 1: Introduction ______________________________ 3
1.1 Introduction _______________________________________ 4

1.2 Project Statement & Significance ______________________ 5


1.3 Proposed Solution __________________________________ 5
1.4 Domain and Limitation ______________________________ 7
1.4.1 Domain _____________________________________________ 8

1.4.2 Limitation ___________________________________________ 8

1.4.2.1 Personal Problem _________________________________ 9

1.4.2.2 Systematic Problem ________________________________ 9

1.5 Methodology ______________________________________ 4


1.5.1 Requirement Analysis__________________________________ 8

1.5.2 System Design _______________________________________ 8

1.5.3 Implementation ______________________________________ 8

1.5.4 Testing _____________________________________________ 8

1.5.5 Maintenance _________________________________________ 8

Chapter 2: Background Information and Related Work ______ 3


2.1 What is the Internet Of Things (IOT) ____________________ 4
2.1.1 Top five advantages of IOT _____________________________ 5

2.1.2 Application area of IOT ________________________________ 5

3|Page
2.2 Similarity Methods __________________________________ 7
2.3 Proposed & Similar System Comparison _________________ 4

2.4 IOT Platform Free & Not Free ________________________ 4


2.4.1 Free _______________________________________________ 5

2.4.2 Not Free ____________________________________________ 5

Chapter 3: System Analysis ___________________________ 3


3.1 Requirements Specification ___________________________ 4
3.1.1 Searching ___________________________________________ 5

3.1.2 Survey and Polls _____________________________________ 5

3.2 Requirement Analysis _______________________________ 7


3.2.1 Functional Requirements _______________________________ 8

3.2.1.1 Family & Guardian ________________________________ 8

3.2.1.2 Police___________________________________________ 8

3.2.1.3 Child ___________________________________________ 8

3.2.1.4 Phone___________________________________________ 8

3.3 Non-Functional Requirements _________________________ 4


3.4 Hardware and Software Requirement ___________________ 4
3.4.1 Hardware Requirements _______________________________ 5

3.4.2 Software Requirements ________________________________ 5

3.4.3 Operating System _____________________________________ 8

3.5 Use Case Diagram __________________________________ 4

3.6 Use Case Description _______________________________ 4

3.7 Sequence Diagram __________________________________ 4


3.7.1 Sequence Diagram for (Family) _________________________ 5

4|Page
3.7.2 Sequence Diagram for (Police) __________________________ 5

3.7.3 Sequence Diagram for (Child) ___________________________ 5

3.8 Class Diagram _____________________________________ 4

Chapter 4: System Design ____________________________ 7


4.1 System Architecture _________________________________ 7
4.1.1 Application Layer_____________________________________ 8

4.1.2 Data Access Layer ____________________________________ 8

4.1.3 Network Layer _______________________________________ 8

4.1.4 Perception Layer _____________________________________ 8

4.2 Database Design ___________________________________ 7


4.2.1 GEO-Localization for lost children using IOT ______________ 8

4.2.2 Family/Guardian Database _____________________________ 8

4.2.3 Police Database ______________________________________ 8

4.2.4 Child Database ______________________________________ 8

4.2.5 Report Database _____________________________________ 8

4.2.6 Phone Database ______________________________________ 8

4.3 User Interface Design _______________________________ 7


4.3.1 Application Logo & Name ______________________________ 8

4.3.2 Log-In Page (Arabic, English) ___________________________ 8

4.3.3 Sign-In Page (Arabic, English) __________________________ 8

4.3.4 Home Page __________________________________________ 8

4.3.5 My Profile Page ______________________________________ 8

4.3.6 Alert Notification Page ________________________________ 8

4.3.7 Report Page _________________________________________ 8

4.3.8 New Report Page _____________________________________ 8


5|Page
Chapter 5: Implementation ____________________________ 7
5.1 Introduction _______________________________________ 7

5.2 Implementation Requirements _________________________ 8


5.2.1 Table of Software Implementation ________________________ 8

5.2.2 Table of Hardware Implementation _______________________ 8

5.3 Implementation Details ______________________________ 8

5.4 Source code for (Parent Application) ___________________ 8

5.5 Source code for (Child Application) ____________________ 8


5.6 I/O Screens _________________________________________________ 8

Chapter 6: Testing __________________________________ 7


6.1 Introduction _______________________________________ 7

6.2 Testing Plan _______________________________________ 8


6.2.1 Testing Strategy ______________________________________ 8

6.2.1.1 Unit Testing ______________________________________ 8

6.2.1.2 Functional Testing_________________________________ 8

6.2.1.3 Acceptance Testing ________________________________ 8

6.2.1.4 Test Objective ____________________________________ 8

6.3 The key function of our application _____________________ 8


6.3.1 Parents _____________________________________________ 8

6.3.2 Child_______________________________________________ 8

6.4 Testing Cases ______________________________________ 8

6.5 Test Result ________________________________________ 8

Conclusions _______________________________________ 7
7.1 Conclusions _______________________________________ 8
6|Page
7.2 Future Work _______________________________________ 8

References _________________________________________ 7

7|Page
Table of Figure

4.2 Figure Database Design _____________________________ 7


4.2.1 Figure of GEO-Localization for lost children using IOT ______ 7

4.2.2 Figure of Family/Guardian Database _____________________ 7

4.2.3 Figure of Police Database ______________________________ 7

4.2.4 Figure of Child Database ______________________________ 7

4.2.5 Figure of Report Database _____________________________ 7

4.2.6 Figure of Phone Database ______________________________ 7

4.3 Figure User Interface Design _________________________ 7


4.3.1 Figure of Application Logo & Name ______________________ 7

4.3.2 Figure of Log-In Page _________________________________ 7

4.3.3 Figure of Sign-In Page_________________________________ 7

4.3.4 Figure of Home Page __________________________________ 7

4.3.5 Figure of My Profile Page ______________________________ 7

4.3.6 Figure of Alert Notification Page ________________________ 7

4.3.7 Figure of Report Page _________________________________ 7

4.3.8 Figure of New Report Page _____________________________ 7

5.6 Figure I/O Screens __________________________________ 7


5.6 Figure of Splash Screen (E/A) ____________________________ 7

5.6 Figure of Log-In (E/A) __________________________________ 7

5.6 Figure of Sign-Up (E/A) _________________________________ 7

5.6 Figure of Recover Password (E/A) _________________________ 7

5.6 Figure of Add Child (E/A)________________________________ 7

8|Page
5.6 Figure of Children (E/A)_________________________________ 7

5.6 Figure of Child Information (E/A) _________________________ 7

5.6 Figure of Profile (E/A) __________________________________ 7

5.6 Figure of Report (E/A) __________________________________ 7

5.6 Figure of Send Report (E/A) ______________________________ 7

5.6 Figure of Map (E/A) ____________________________________ 7

9|Page
 Acknowledgment

The completion of this study could not have been possible without the expertise of
(Dr. Manal Ayadi) our beloved thesis adviser, she has been sitting on our panel and
taking the time to read our thesis and share her thought about it. We would also like
to thank our university who gave us the golden opportunity to build this application.
Finally, we would like to thank our families, because without them none of this would
indeed be possible.

 Abstract

The graduation project will be able to help the family after God in protecting their
child from being lost, and we are hoping that it will make the child feel safer by
wearing the watch, it will also help police with tracking their location.

In this project through analyzing the main problem, which is a missing child, with
reading a lot of articles that are related to our project and have used similar methods,
we have found the best solution which is designing an application that is connected to
a bracelet to localize child location. So, if we want to achieve such kind of system, we
specified our requirements from functional to non-functional. At the end of the
graduation project report, we have designed a prototype version of our application
that will demonstrate the interface and easiness, the usefulness of using the
application.

 Keyword

Child, Family, policy, Bracelet, Application.

10 | P a g e
Chapter 1: Introduction

11 | P a g e
1.1 Introduction:
The phenomenon of missing children under the age of 18 has been reported
worldwide and is becoming a huge global concern. It has been estimated that at least
eight (8) million children go missing each year (International Centre for Missing and
Exploited Children). [1]
Our graduation project is a keystone of geo-localization using IOT, so “the internet of
things” refers to using mechanical and digital machines, objects, animals, or people.
IOT is a type of network connect to anything with the Internet based on stipulated
protocols through information sensing equipment to conduct information exchange
and communications network without requiring human-to-human or human-to-
computer interaction, in order, to achieve smart recognitions, positioning, tracking,
monitoring, and administration.
The main objective of our project is to develop an application that targets the lost
children with the help of IOT definition throughout a chip connected to an application
and developing a system that is concerned with finding the specific location of the
child so it will help the families to find them before it is too late.

1.2 Project Statements & Significance:


The problem is parents had no alternative on how to monitor their kids. This could
lead them easily to become prey to kidnapping or to get lost and not knowing the way
back.
A total of lost children in Australia, an estimated 20,000, in Canada, an estimated
45,288, in Germany, an estimated 100,000, in India, an estimated 96,000, in
Jamaica, an estimated 1,984, in Russia, an estimated 45,000, in Spain, an estimated
20,000, in the United Kingdom, an estimated 112,853, in the United States, an
estimated 460,000 children are reported missing every year. [2]
Furthermore, no fast action can be taken to prevent this problem before it too late for
parents to save their child.

1.3 Proposed Solution (System):


Parents can only call the authority and report about their missing children without
any possible lead about the location. This makes the investigation or the process to
locate and finding their children difficult thus time-consuming. An early preparation
or security measure is needed to avoid this kind of problem from occurring. So, our
project will have a great impact on our society because it will prevent the children
from being (Lost, Kidnapped). The app is designed to provide aspects that will help
with the time-consuming, lost kidnapping by saving time with knowing the exact
location for the child. We are willing to design an application all about the geo-
localization using IOT technology to locate the lost child as fast as possible,
throughout a designed chip that will contain updated signals of child location, that
could be a simple kind of accessories (bracelet, necklaces, rings), or under the skin.

12 | P a g e
1.4 Project Domain and Limitation:

1.4.1 Domain:
The project domain targets newborn children to legal age, it’s used by their family,
the boundaries of the application will be around Saudi Arabia and maybe after we
publish it, we will try to develop it in another systematic way so it can be solid all
around the world.
The delimitation of system, interface, rules. The topic we want to consider during
the development (that map should be updated frequently if the chip stops sending a
signal the family should be notified by the application, ease to use), and some that
we will not keep an eye on (how many family members can use the application, the
icons places).

1.4.2 Limitation:

The project boundaries can split into two, systematic problems or personal
problems.

1.4.2.1 Personal problem is related to the user’s usage of the application, the
phone could be out of battery when the kid happens to be lost. It could also
reach the extent of the breakage of the phone that holds the chip information
of the lost child, the misuse of the bracelet may cause many damages to it, the
child could take off the bracelet, which will cause them to lose the bracelet.

1.4.2.2 Systematic problem is related to the outside world and/or the system, for
example, when the child is lost there could be problems with the signals which
will affect the speed of locating the child, and the system should be
maintained (as all systems do).

13 | P a g e
1.5 Waterfall Model:

1.5.1 Requirement Analysis: all possible requirements of the GEO-localization of


lost children using the IOT application to be developed are captured in this phase and
documented in a requirement specification document.

1.5.2 System Design: the requirement specifications from the first phase are studied
in this phase and the system design is prepared. This system design helps in
specifying hardware and system requirements and helps in defining the overall
system architecture.

1.5.3 Implementation: with inputs from the system design, the system is first
developed in small programs called units, which are integrated with the next phase.
Each unit is developed and tested for its functionality, which is referred to as Unit
Testing.

1.5.4 Testing: all the units developed in the implementation phase are integrated into
a system after testing each unit. Post integration the entire system is tested for any
faults and failures.

1.5.5 Maintenance: after the successful completion of the testing phase, we will
release the “GEO-localization of lost children using IOT application” there are some
issues that come up in the client environment. To fix those issues, patches are
released. Also, to enhance the product some better versions are released. Maintenance
is done to deliver these changes in the customer environment. [3]

14 | P a g e
Chapter 2: Background
Information and Related Work

15 | P a g e
2.1 What is the Internet Of Things (IOT)?
In general, IOT encompasses everything connected to the internet. But it is increasingly
being used to defines objects that communicate with each other. Simple it is made up of
connected devices to gather information, analyse it and create action. So, it is about
network, device, data. So, the purpose of IOT is to connect and exchange data with
other devices and systems over the internet.

2.1.1 Top five advantages of the IOT:


1. Cost reduction
2. Efficiency and productivity
3. Business opportunities
4. Customer experience
5. Mobility and agility

2.1.2 Application area of IOT:

1. Smart Grid and Energy Saving: by offering valuable information to the


end-user about their consumption patterns and the best way to reduce
their energy expenditure.
2. Traffic Monitoring: such as google maps which we use to inform us in
contribute to traffic.
3. Health: its sensors are connected to patients that allow doctors to
monitor a patient outside the hospital.
4. Hospitality: whit the implementation of electric keys, which are sent
directly to the mobile devices of each guest, it is possible to automate
various interactions.
5. Water Supply: sensor, either incorporated to adjusted externally to water
meters it allows the company to understand the behaviour of consumer
detecting faults in the supply service.
6. Wearable: such as virtual glasses, fitness band Assists with geolocation,
it monitors the efficient routes, so by that (performance analysis,
elementary control, and fuel-saving). [4]

16 | P a g e
2.2 Similarity System

i. Pawscout
A digital pet tag and tracker for dogs and cats with social GPS and BLE
connectivity, which works with a connected mobile app and a worldwide tracking
community to keep pets safe. It is attached to the pet collar. [5]

 Features:
- Smart pet tracking
- Online community
- Virtual leash
- Detailed digital profile
- Social GPS: finding the lost pets easily

ii. GreenIQ
Control your garden’s lawn irrigation & lighting from anywhere. With GreenIQ
smart sprinklers controller, you will save up to 50% on your outdoor water bills.
[6]

 Features:
- Control irrigation saves water
- Connect to leading home automation platforms
- Add accessories to your smart garden hub

iii. Find My iPhone


The app can locate iPhones, iPads, Mac Computers, Apple Watches, and AirPods
connected to the same iCloud account. Locations of your devices appear on a
map. [7]

 Features:

- Sign-In: signing in with your apple id and password.

- Locate devices: see the location of the device on a map.

- Play a sound: play a sound on a lost device to help you find it.

- Mark a device as lost: use Lost Mode to protect a lost device so that others cannot
access your personal information.

- Erase a device: remotely erase all your personal information from the device.

17 | P a g e
iv. Google Map
Is a web mapping service developed by, the maps service can be used for your
location determination, users can choose whether they are going by foot, by bike,
by public transport or by car.

 Features:
- Directions for driver
- Search for shops, restaurants
- Provides you with option roads that have a similar estimated time of arrival
(ETA)
- Rating of places
- Delays & disruption route comparison

v. Uber
In cities where Uber operates, use the uber app to request a ride. When a nearby
driver accepts your request, your app displays an estimated time of arrival for the
driver heading to your pickup location. Your app notifies you when the driver is
about to arrive.

 Features:
- Scheduled Rides
- your driver information
- Real-time tracking of your driver
- Driver review and payment
- Multiple payment methods

2.3 Proposed & Similar System Comparison:


In this part we will compare our app with similar other application features:

Language Location
App Name Ease of Use Tracking Time-Saving
Arb / Eng Alert

GOE-localization of
✓/✓ ✓ ✓ ✓ ✓
lost children using IOT

Pawscout ✗/✓ ✓ ✓ ✓ ✓
GreenIQ ✗/✓ ✓ ✓
Find My iPhone ✗/✓ ✓ ✓ ✓
Google Maps ✓/✓ ✓ ✓
Uber ✓/✓ ✓ ✓ ✓ ✓

18 | P a g e
2.4 IOT Platforms Free & Not Free

2.4.1 Free Platforms:

i. Axonize
Has developed a disruptive, multi-app architecture, purpose-built for
service providers, and end customers, that enables the deployment of fully
customized smart solutions across all applications, verticals, and device
types. [8]
ii. FogWing
Is the comprehensive industrial available as a service on a subscription
basis, is a no-code platform. It can help to achieve industrial automation;
the user may build custom IOT solutions to prebuilt IOT applications. [8]
iii. UpSwift.io
UpSwift.io provides a plug play device management platform for IOT and
Linux devices. users can deploy OTA. In less than 60 seconds users can be
able to connect any type of Linux or IOT device. [8]

2.4.2 Not Free Platforms:

i. Webnms
A tool that strives to bring simplicity to the IOT platform through easy
integrations, smooth onboardings, and a dedicated team of professionals.
Whether you are in the healthcare, manufacturing, or agriculture space
Webnms can help deploy IOT solutions throughout your business. [9]

ii. ThingWorx
Is an IOT platform owned by PTC, a leader in industrial business
solutions. ThingWorx leverages this industry expertise with IOT
technology to create solutions that are tailored to industrial and energy
solutions.
With ThingWorx you can use IOT sensors to monitor equipment in the
supply chain, and ultimately reduce costs and predict maintenance
requests based on sensor information. [9]

iii. AWS IOT


An Amazon IOT platform that puts its an existing network of cloud
servers to use to help move data from physical sensors to servers across
the world. They have a massive advantage over other businesses when it
comes to implementing a global IOT platform. [9]

19 | P a g e
Chapter 3: System Analysis

20 | P a g e
3.1 Requirements Specification

We have tried many ways to gather information to specify our project requirements
such as:
3.1.1 Searching:
We searched for similar systems that use the same method as our project and
came up with several ways of how to distinguish our project from them.
3.1.2 Survey and Polls:
We’ve used these two methods to know the population thoughts and opinion of
our project polls are questions that do not require detailed responses they are the
only question that has one answer, they are antibiosis of a survey because survey
requires detailed extension feedback, also there must be text comment so every
person will have their own opinion.

Our Question Received Answers


Do you have children under the legal
age?

‫ًٔ؟‬ٛٔ‫ً٘ ٌذٌه طفً ذحد اٌسٓ اٌما‬

Did you ever lose a child in a public


place?

‫فمذخ طفال فً ِىاْ عاَ؟‬ٚ ‫ً٘ سثك ٌه‬

In your opinion why do so many Some of the received answers:


children go missing? :)‫صٍرٕا‬ٚ ً‫تح اٌر‬ٛ‫)تعض األظ‬

‫ْ؟‬ٚ‫تشأٌه ٌّارا وصٍش ِٓ األطفاي ٌفمذ‬ ٌُٙ‫عذَ ِراتعح اطفا‬ٚ ً٘‫ اّ٘اي األ‬-
ً‫ وصشج حشوح اٌطفً فً األِاوٓ اٌعاِح لذ ٌسثة فً ضٍاع اٌطف‬-
‫ْ خثش‬ٚ‫ُ تذ‬ٍٙ‫ُ تعٍذا ً عٓ عائ‬ٙ‫ر٘ات‬ٚ ‫ ٌعذَ اٌرشوٍض تاألِاوٓ اٌعاِح‬-
َ‫االعرّاد اٌراَ عٍى اٌخذ‬- ‫االدسان‬ٚ ً‫ع‬ٌٛ‫عذَ ا‬ٚ ‫ي األطفاي‬ٛ‫ تسثة فض‬-
ْٛ‫ستّا ٌى‬- ُٙ‫ٌحشور‬ٚ ٌُٙٛ‫ ٌسشعح شذ أرثاٖ األطفاي ٌألشٍاء ِٓ ح‬-
‫ تسثة أخشاط اٌطفً تاٌٍعة‬ٚ‫تسة ظشأج اٌطفً أ‬

21 | P a g e
Did you ever helped other families
with finding their missing child?

ٍُٙ‫س عٍى طف‬ٛ‫ً٘ سثك ٌه ِساعذج عائٍح فً اٌعص‬


‫د؟‬ٛ‫اٌّفم‬

If you ever heard of a child that been


missing which method, would you
follow?

‫ فّا اٌطشٌمح‬،ً‫عٕذِا ذسّع\ٌٓ عٓ حاٌح فمذاْ طف‬


‫ا؟‬ٌٕٙ\‫ا‬ٙ‫إٌّاسثح اٌرً لذ ذرثع‬

Do you think your chosen method


would be effective?

ْٛ‫ا لذ ذى‬ٙ‫ً٘ ذعرمذ\ٌٓ أْ اٌطشٌمح اٌرً اخرشذ‬


‫فعاٌح؟‬

Have you ever heard of a bracelet


that is connected to an application
that can identify the location of a
child?

ٕٗ‫اس ِمرش ترطثٍك ٌّى‬ٛ‫ِا عٓ إس‬ٌٛ ‫ً٘ سّعد‬


‫لع اٌطفً؟‬ِٛ ‫ذحذٌذ‬
If this bracelet was invented, do you
think it would be helpful?

ٗٔ‫ٌٓ تأ‬/‫اس ً٘ ذعرمذ‬ٛ‫إرا ذُ اخرشاع ٘زا اٌس‬


‫ْ ِفٍذ ًا؟‬ٛ‫سٍى‬

22 | P a g e
‫‪Which feature that you would look‬‬ ‫‪Some of the received answers:‬‬
‫?‪up to in the bracelet or application‬‬ ‫)تعض األظ‪ٛ‬تح اٌرً ‪ٚ‬صٍرٕا)‪:‬‬

‫ِا اٌٍّضج اٌرً ذ‪ٛ‬د\ٌٓ تأْ ذر‪ٛ‬اظذ فً اٌس‪ٛ‬اس أ‪ٚ‬‬ ‫‪ -‬سٍى‪ٕ٘ ْٛ‬ان احرّاٌٍٗ وثٍشٖ فً ِعشفٗ ِىاْ اٌطفً لثً ف‪ٛ‬اخ اال‪ٚ‬اْ‬
‫اٌرطثٍك؟‬ ‫‪ -‬ذحذٌذ ِ‪ٛ‬لع اٌطفً‬
‫‪ -‬عٓ طشٌك ذرثعً ٌٗ تاسرخذاَ اٌع‪ٛ‬اي ‪ِٚ‬عشفح وً ِىاْ ٌز٘ة اٌٍٗ‬
‫‪ -‬ترحذٌذ ِىأٗ ‪ٚ‬عذَ ضٍاع اٌ‪ٛ‬لد فً اٌثحس تأِاوٓ اٌرً ال ٌر‪ٛ‬اظذ ت‪ٙ‬ا‬
‫‪ٌ -‬ى‪ ْٛ‬س‪ٛ‬اس ِرصً تاٌ‪ٛ‬اٌذٌٓ‬
‫‪ -‬ذرثع حشوح اٌطفً عٓ طشٌك اٌع‪ٛ‬اي‬
‫‪ -‬عٓ طشٌك اٌشٍٔٓ إرا اترعذ اٌطفً عٓ االَ‬
‫‪ -‬ستطٗ ِع االً٘ تاسرخذاَ ‪ٚ‬سائً اٌرمٍٕح اٌحذٌصح‬
‫‪ -‬تشٔاِط ذرثع اٌس‪ٛ‬اس‬
‫‪ -‬عٓ طشٌك ششٌحح ذحذد ِىاْ اٌطفً‬
‫‪ -‬تأسساي ذٕثٍٗ ٌٍس‪ٛ‬اس اٌزي ذّرٍىٗ االَ‬
‫‪ -‬اٌعص‪ٛ‬س عٍٍ‪ ُٙ‬عٓ طشٌك ‪GPS‬‬
‫‪ -‬تأحذاز ص‪ٛ‬خ أ‪ ٚ‬إضاءج ‪٘ٚ‬ضاص‬
‫‪ٌٛ -‬ضع تٗ سلُ ظ‪ٛ‬اي االَ ‪ٚ‬االب ‪ٌٚ‬فضً اٌضا ‪ٚ‬ضع ساتظ ٌّ‪ٛ‬لع إٌّضي‬
‫‪ -‬ترحذٌذ ِ‪ٛ‬لعٗ حرى اْ واْ خاسض ٔطاق اٌشثىح‬
‫‪ -‬ششط اْ ال ٌى‪ ْٛ‬س‪ ًٙ‬اٌخٍع؛ ‪ٚ‬ال ٌرأشش تاٌّاء؛ ٌصثح ٌعًّ عٓ طشٌك‬
‫اٌرصفٍش فً ظ‪ٛ‬اًٌ حاي اترعذ عًٕ ِسافح ِرش‬
‫‪ -‬إرا اترعذ اٌطفً ٌٕثٗ االً٘ عثش اٌرطثٍك فً اٌع‪ٛ‬اي‬
‫‪ -‬عثاسج عٓ حساط ٌشسً اشعاساخ تّىاْ اٌطفً‬
‫‪ -‬تحفظ اٌ‪ٛ‬لد اٌضائع فاٌثحس حٍس ٌرُ ذحذٌذ اٌّ‪ٛ‬لع اٌّ‪ٛ‬ظ‪ٛ‬د فٍٗ ِثاششج‬

‫‪23 | P a g e‬‬
3.2 Requirement Analysis:
3.2.1 Functional Requirements:
Functional requirements specify how a system should work and behave so it is
a set of the list that the system must provide to the end-user.

3.2.1.1 Family& Guardian:


- The family shall be able to log in
- The family shall be able to track child location
- The family shall be able to connect the bracelet to the application
- The family shall be able to modify the location of the child
- The family shall be able to delete their child information if
unauthorized access happens
- The family shall be able to inform the police about the child
location
- The family shall be able to share their child location with policy
- The family shall be able to modify the status of their child
- The family shall be able to log out

3.2.1.2 Police:
- The police shall be able to log in
- The police shall be able to post an announcement
The police shall be able to see the location of the child
The police shall be able to know how long the child been missing
The police shall be able to log out

3.2.1.3 Child:
- The child shall be able to send an alert to the parent
- The child shall be able to talk to the parents through a (walkie-
talkie)

3.2.1.4 Bracelet:
- The bracelet shall be able to sense the location of the child
- The bracelet shall be able to send alerts to the Family & Guardian
- The bracelet shall be able to make the child and his Family&
Guardian talk through (walkie-talkie)

24 | P a g e
3.3 Non-Functional Requirements:
Defines system attributes, they serve the system as a constraints restriction on the
designed system. They ensure the useability and effectiveness of the entire system.
Non-Functional requirements are persistent and constraints. In other words, it focuses
on user expectations of the system.

Non-Functional
The system response time for user action should take
Performance
less than a second.
Availability The system will be available at any time anywhere.
The system will ensure that there is no unauthorized
Security access to the application and only the allowed parent
can access their account.
The ability of the application system to recover from a
Recoverability failure in the system and go back to being fully
operational within less than 5 minutes.
The system is user-friendly and easy to use for
Usability
programmers and non-programmer people.
The system can face and manage a high number of
Scalability
users.
The application system should be free of mistakes and
Accuracy share with the parents the specific location of their
child.

25 | P a g e
3.4 Hardware and software requirement:
3.4.1 Hardware Requirements:

o Bracelet:
To connect it with the application and start tracking your child's location.

3.4.2 Software Requirements:

o Wi-Fi:
So, the application can run on your mobile phone.

o Mobile Phone:
2GB capacity is enough for downloading, testing, and using the system.

o Bluetooth:
To connect the bracelet to the application.

3.4.3 Operating System:

o Apple IOS:
The operating system runs apple’s line.

- iPhone:
Requires IOS 14.4.1 or later.
- iPad:
Requires IOS 14.4.1 or later.
- Apple Watch:
Requires watch OS 2.2 or later.

o Android:
System based on a modified version of the Linux kernel.

- Galaxy:
Requires 11.0.0 version or later.
- Tablet:
Requires 11.0.0 version or later.
- Galaxy Watch:
Requires 1.012 version or later.

26 | P a g e
3.5 Use Case Diagram:
The use cases represent only the functional requirements of a system.
We have used it to summarize some of the relationships between use cases, actors,
and systems.

27 | P a g e
3.6 Use Case Description:
Text-based narrative of a functionality comprised of detailed, step-by-step interaction
between the actor and the system. It describes the outcomes of an action taken to
accomplish a specific goal.

Use Case Log-In


Actors Family/Guardian, Police
This use case allows users to log into the
Description system to access all relevant information
and functions.

Use Case Inform Police


Actors Family/Guardian
This use case allows the user to inform
Description police of the whereabouts of the child
that is missing or lost.
Extensions Announce Missing Child

Use Case Track Child’s Location


Actors Family/Guardian, Police
This use case allows user to accurately
track the child and their whereabouts
Description
whether the child is missing/kidnapped
or not.
Extensions Share Child’s Location

Use Case Delete Child’s Information


Actors Family/Guardian
This use case allows users user to delete
Description the child’s information from the
system/database.

Use Case Send Alert


Actors Child
This use case allows the user (child) to
send an alert to the family/guardian
Description
informing them if they are
lost/kidnapped.

28 | P a g e
Use Case Talk to Parents
Actors Child
This use case allows the user (child) to
Description speak to their parents using a walkie-
talkie in case of no signal/internet.

Use Case Announce Missing Child


Actors Guardian/Family
This use case allows the user to give
Description information to the police about the child
for preparing an announcement.
Inclusions Post Announcement.

Use Case Post Announcement


Actors Police
This use case allows the police after they
Description have the information about the missing
child to post an announcement.
Inclusions Announce Missing Child

Use Case Share Child's Location


Actors Guardian / Family
This use case allows the user to share
Description the child's location with other parties to
participate in finding the child.

Use Case Track How Long the Child Is Missing


Actors Police
This use case allows the user (Police) to
Description stay updated about how long the child
went missing.

Use case Log out


Actors Family & Guardian, police
This use case allows users to log out
Description
from system.

29 | P a g e
3.7 Sequence Diagram:

The sequence diagram is a type of interaction diagram, it describes how and in


what order a group of objects works together.

3.7.1 Sequence Diagram for (Family):

30 | P a g e
3.7.2 Sequence Diagram for (Police):

3.7.3 Sequence Diagram for (Child):

3.8

Class Diagram:
31 | P a g e
The class diagram is the main building block of object-oriented modeling, it describes
the structure of the system by showing the system classes, attributes, methods, and the
relation between classes.

32 | P a g e
Chapter 4: System Design

4.1System Architecture
It shows the types of tiers, and each tier is maintained and developed independently.

33 | P a g e
4.1.1 Application Layer

The top level of the application layer is the user interface. For our project, the
users will be (Family & Gradient) they will do the advanced work on the
application. They can track the child or share their child location with the police.
Of course, the parent can add their child information, and delete the information if
unauthorized access happens.

4.1.2 Data Access Layer

Child information is stored and can be retrieved from the database. The
information can be edited or removed.

4.1.3 Network Layer

The network layer in our project will be the main root because it will build the
connection between the bracelet and the application and will make sure that there
is a connection between the application and policy.

4.1.4 Perception Layer

The bracelet contains sensors that are used to sense the location of the child, the
bracelet can modify the child location on the map through the wireless
connection.

4.2 Database Design

4.2.1 GEO-localization for lost children using IOT:

34 | P a g e
Figure 4.2.1: GEO-localization for lost children using IOT

- GEO-localization for lost children using IOT: has 5 tables (Child Database,
Family/Guardian, Police Database, Report Database, Bracelet Database).

4.2.2 Family/Guardian Database:

Figure 4.2.2: Family/Guardian Database

- Family Database: has 5 fields (User ID, User Name, User Password, User Address,
User Mobile).

4.2.3 Police Database:

Figure 4.2.3: Police Database

- Police Database: has 6 fields (User ID, User Dep ID, User Name, User Password,
User Mobile, User Address).

4.2.4 Child Database:

35 | P a g e
Figure 4.2.4: Child Database

- Child Database: has 3 fields (User ID, User Name, User DOB).

4.2.5 Report Database:

Figure 4.2.5: Report Database

- Report Database: has 4 fields (Report ID, Date, Report Description, Report Status).

4.2.6 Bracelet Database:

Figure 4.2.6: Bracelet database

- Bracelet Database: has 2 fields (Bracelet ID, Child ID).

36 | P a g e
4.3 User Interface Design

4.3.1 Application Logo & Name:

Figure 4.3.1: Application Logo & Name

37 | P a g e
4.3.2 Log-in Page (Arabic, English):

Figure 4.3.2: Log-in Page

- Log-in Page: the user must-up the form contains (National ID/ Iqama ID Number,
Password).

38 | P a g e
4.3.3 Sign-in Page (Arabic, English):

Figure 4.3.3: Sign-in Page

- Sign-in Page: the user must fill up the form


contains (National ID/ Iqama ID Number, Date of
Birth).

4.3.4 Home Page:

39 | P a g e
Figure 4.3.4: Home Page

- Home Page: in this page family can (Check Existing Child Location, Add Child,
Certify Bracelet Number, Personal Information).

4.3.5 My Profile Page:


40 | P a g e
Figure 4.3.5: My Profile Page

- My Profile Page: in this page, the user can change account sitting.

4.3.6 Alert Notification Page:

41 | P a g e
Figure 4.3.6: Alert Notification Page

- Alert Notification Page: the family can see their child's location who has sent them
an alert message.

42 | P a g e
4.3.7 Reports Page:

Figure 4.3.7 : Report Page

- Report Page: the family can see their child's report status.

4.3.8 New Report Page:

43 | P a g e
Figure 4.3.8: New Report Page

- New Report: the family can open a new report to the police if they have lost their
child.

44 | P a g e
Chapter 5: Implementation

5.1 Introduction

45 | P a g e
In this chapter, we will describe the implementation of the system including
implementation requirements, the fragment of the main functions in the system, and I/O
screens.

5.2 Implementation Requirements

The following are the software and hardware requirements, which offer the suitable
feature to meet the system needs during the implementation stage.

5.2.1 Table of Software Implementation

Software Usage

Developments Environment Android Studio Version

Programing Language Dart, Flutter

Database Firebase

API Google Map

5.2.2 Table of Hardware Implementation

Hardware Usage

Processor Intel Core i5

RAM 8 GB Memory

Storage 128 GB SSD

Device HP PAVILION

Operating System Windows 10

Samsung Galaxy S7 edge Android version 7.0

46 | P a g e
5.3 Implementation Details

This section will introduce the implementation phase of the GP management system in a
short view using the hardware and software mentioned in the requirement section.
The graduation project was written by Dart, Flutter, the Android Studio programming
language for both IOS and Android.
The database is used to store all tables and records Firebase.

- Android Studio:

Android studio is the official integrated development environment (IDE)


for Google's Android operating system, built on JetBrains' IntelliJ IDEA
software and designed specifically for Android development.

- Firebase:

It’s a Google-backed application development software that enables developers to


develop IOS, Android, and Web apps. Also, Firebase provides tools for tracking
analytics, reporting, and fixing app crashes and it's considered an IoT
development platform.

- Dart, Flutter:

Dart is the programming language used to code Flutter apps. Dart looks a bit like
C and is an object-oriented programming language. So, if you prefer the C
languages or Java, Dart is the one for you, and you'll likely be proficient in it.
Dart is not only used for mobile app development but is a programming language.

5.4 Source code for (Parent Application):

47 | P a g e
 Add Child:

class AddChild extends StatefulWidget {


@override
State<StatefulWidget> createState() =>AddChildState();
}
class AddChildState extends State<AddChild>{
late String name;
GlobalKey<FormState> formState = new GlobalKey<FormState>();
File image = new File("");
String fileName ="";
submit() async {
var form = formState.currentState;
if (form!.validate()) {
form.save();
if (image.path == "") {
FA.showInfoMsg(context, "Please upload child image".tr());
return; }
final ProgressDialog progressDialog = ProgressDialog(
context, isDismissible: false);
progressDialog.style(
message: 'Add'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");}
else {
await progressDialog.show();
var child_id = randomNum();
List list = Pref.get_random_list();
do {
if (list.contains(child_id)) {
child_id = randomNum();}
else {
break; }}
while (true);
Reference reference = FirebaseStorage.instance.ref(
"${Database.loggedUserId()}/${child_id}${fileName}");
UploadTask uploadTask = reference.putFile(image);
uploadTask.snapshotEvents.listen((event) async {
if (event.state == TaskState.success) {

48 | P a g e
String imgUrl = await event.ref.getDownloadURL();
var child_id = randomNum();
List list = Pref.get_random_list();
do {
if (list.contains(child_id)) {
child_id = randomNum();}
else {
break; }}
while (true);
Child child = new Child(
child_id, name, imgUrl, Database.loggedUserId());

Database.children().doc(child_id).set(child.toMap()).then((
value) async {
await progressDialog.hide();
Navigator.pop(context);
}).catchError((error) {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
}); }
}).onError((error) {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
});}}}
@override
void initState() {
super.initState(); }
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [
SystemUiOverlay.top ]);
return Scaffold(
appBar: AppBar(title: Text(
"Add Child".tr(), style: DesignHelper.barTitleStyle,)),
body: Form(key: formState,
child: Container(alignment: Alignment.topCenter,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.vertical, child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
Container(

49 | P a g e
margin: EdgeInsets.symmetric(horizontal: 20),
child: TextFormField(
cursorColor: Theme
.of(context)
.primaryColor,
style: DesignHelper.fieldStyle,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp("[a-zA-Z\\s]"))],
keyboardType: TextInputType.name,
decoration: InputDecoration(
labelText: "Child name".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon: Icon(Icons.person, color:
Theme
.of(context)
.primaryColor),
enabledBorder: DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder:
DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper
.fieldErrorBorder
),
validator: (text) {
if (text!.trim().isEmpty) {
return "Full name".tr() + " " +
"is required".tr();0}
return null;},
onSaved: (text) {
name = text.toString();
},)),
SizedBox(height: 30),
GestureDetector(child: Container(
margin: EdgeInsets.symmetric(horizontal: 20),
width: double.infinity,
height: 200,
padding: EdgeInsets.symmetric(horizontal: 10),
child: image.path == "" ? Container(
alignment: Alignment.center,
child: Row(mainAxisAlignment:
MainAxisAlignment
.center, children: [

50 | P a g e
Icon(Icons.upload, color:
MyColors.primary,),
Text(
"Upload child image".tr(), style:
TextStyle(
color: MyColors.gray,
fontWeight: FontWeight.bold,
fontSize: 18
), textAlign: TextAlign.center)
])) : Image.file(image,
fit: BoxFit.fill)
), onTap: () async {
FilePickerResult? result = await
FilePicker.platform
.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'png'], );

if (result != null) {
PlatformFile file = result.files.first;
setState(() {
fileName = file.name;
image = new File(file.path.toString());
});}},),
SizedBox(height: 35),
SizedBox(width: DesignHelper.buttonWidth2,
height: DesignHelper.buttonHeight2,
child:
ElevatedButton(onPressed: () {
submit();
}, child: Text("Add").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 15),],))))); }
String randomNum() {
var rng = new Random();
return (rng.nextInt(900000) + 100000).toString();}}

 Child Information:

51 | P a g e
class ChildInfo extends StatefulWidget {
@override
State<StatefulWidget> createState() =>ChildInfoState();}
class ChildInfoState extends State<ChildInfo>{
late Child child;
@override
void initState(){
super.initState();}
@override
Widget build(BuildContext context) {
final Map<String, Object> receivedData =
ModalRoute.of(context)!.settings.arguments as Map<String, Object> ;
child = receivedData['child'] as Child;
return Scaffold(
appBar: AppBar(title: Text("Child Info".tr(),style:
DesignHelper.barTitleStyle),actions:menu1()),
body:Container(
child:FutureBuilder(
future: Database.children().doc(child.child_id).get(),
builder: (context,AsyncSnapshot<DocumentSnapshot<Object?>>
snapshot) {
switch (snapshot.connectionState) {

case ConnectionState.waiting: return


Center(child:CircularProgressIndicator());
default:
if (snapshot.hasData) {
Child ch = Child.fromMap(
snapshot.data!.data() as Map<String,dynamic>);
child = ch;
return
Container(alignment:Alignment.topCenter,width:double.infinity,child:Sin
gleChildScrollView(scrollDirection: Axis.vertical,child:Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
Image.network(
ch.imgUrl,
width: 200,
height: 150, ),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Text("${ch.name}",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18)),),
SizedBox(height: 20),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[

52 | P a g e
Text("Child ID".tr()+" : ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 17)),
Text("${child.child_id}",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
fontSize: 17))]),),
SizedBox(height: 20),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text("Child Status".tr()+" : ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 17)),
Text("${(child.is_online)?"Online".tr():"Offline".tr()}",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
fontSize: 17))]),
),
SizedBox(height: 40),
SizedBox(width: DesignHelper.buttonWidth2,
height: DesignHelper.buttonHeight2,
child:
ElevatedButton(onPressed: () {
track();
}, child: Text("Track child").tr(),
style: DesignHelper.buttonStyle,
)),])));}
else{
return SizedBox.shrink();}
};})));}
track() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
FA.showErrorMsg(context, "Please enable location".tr());}
else {
LocationPermission permission;
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
FA.showErrorMsg(context, "Please grant storage
permission").tr();
return; }
return; }
if (permission == LocationPermission.deniedForever) {
FA.showInfoMsg(context, "Please grant location permission from
settings").tr();
openAppSettings();

53 | P a g e
return;
}
if (await FA.isInternetAvailable())
Navigator.of(context).pushNamed("child_map", arguments:
{"child": child});
else
FA.showErrorMsg(context, "No internet").tr();}}
menu1() {
return [
PopupMenuButton<int>(
icon: Icon(Icons.person),
itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
new PopupMenuItem<int>(
value: 0, child: new Text('Send report'.tr())),
new PopupMenuItem<int>(
value: 1, child: new Text('Update name'.tr())),
new PopupMenuItem<int>(
value: 2, child: new Text('Update image'.tr())),
new PopupMenuItem<int>(
value: 3, child: new Text('Delete child'.tr()))],
onSelected: (int value) {
switch(value){
case 0:
send_report();
break;
case 1:
update_name();
break;
case 2:
update_image();
break;
case 3:
delete_child();
break; }})];}
send_report(){
Navigator.of(context).pushNamed("send_report",arguments:
{"child":child});}
update_name(){
Navigator.of(context).pushReplacementNamed("update_child_name",argument
s: {"child":child});}
update_image(){
Navigator.of(context).pushReplacementNamed("update_child_image",argumen
ts: {"child":child});}
delete_child(){
AwesomeDialog(
context: context,
title: "Are you sure delete child?".tr(),
isDense: true,
btnCancelText: "no".tr(),
btnCancelOnPress: (){},
btnCancelColor: Colors.blue,
btnOkText: "yes".tr(),
btnOkColor: Colors.blue,

dismissOnBackKeyPress: false,
dismissOnTouchOutside: false,
customHeader: Column(

54 | P a g e
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 20),
Icon(Icons.warning,color: Colors.red,size: 55),],),
btnOkOnPress: (){
delete();
}, )..show();}
delete() async {
final ProgressDialog progressDialog = ProgressDialog(
context, isDismissible: false);
progressDialog.style(
message: 'Delete child'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),
);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");
}
else {
progressDialog.show();

FirebaseStorage.instance.refFromURL(child.imgUrl).delete().then((value)
{
Database.children().doc(child.child_id).delete().then((value){
progressDialog.hide();
Fluttertoast.showToast(
msg: "Delete done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0 );
if(Navigator.canPop(context)){
Navigator.pop(context);}
else{
SystemNavigator.pop(); }
}).catchError((error) async {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
});
}).catchError((error) async {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
});}}}

 Child Map:

55 | P a g e
class ChildMap extends StatefulWidget {
@override
State<StatefulWidget> createState() =>ChildMapState();}
class ChildMapState extends State<ChildMap> {
late GoogleMapController gmc;
Child child = new Child("","","","");
late LatLng current_latLang;
Set<Marker> markers = {};
late StreamSubscription<Position> ps;
static final CameraPosition defaultPosition = CameraPosition(
target: LatLng(0, 0),
tilt: 59,
zoom: 19.151926040649414, );
void mapSettings() async {
final ProgressDialog progressDialog = ProgressDialog(
context, isDismissible: false);
progressDialog.style(
message: 'Loading map...',
messageTextStyle: TextStyle(
color: MyColors.primary,
fontSize: 18.0,
fontWeight: FontWeight.normal), );
// progressDialog.show();
Position position = await Geolocator.getCurrentPosition();
setState(() {
final Map<String, Object> receivedData = ModalRoute
.of(context)!
.settings
.arguments as Map<String, Object>;
child = receivedData['child'] as Child;
DocumentReference<Object?> reference =
Database.children().doc(child.name==""?"1":child.child_id);
reference.snapshots().listen((snapshot) {
if(snapshot.exists){
Child child = Child.fromMap(snapshot.data() as
Map<String,dynamic>);
childListener(child);
}});
current_latLang = LatLng(position.latitude, position.longitude);
gmc.moveCamera(CameraUpdate.newLatLng(current_latLang));
Marker m1 = Marker(markerId: MarkerId("child"),
position: current_latLang
,
icon:
BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen));
markers.add(m1);});
//progressDialog.hide();}
childListener(Child child){
if(child.is_online){
childMove(child.lat,child.lng);}
else{
Fluttertoast.showToast(
msg: "Child is offline".tr(),

56 | P a g e
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 16.0 );
Navigator.pop(context);} }
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
mapSettings();
});}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: Text(
"Track child".tr(), style: DesignHelper.barTitleStyle,),),
body: Container(
child: GoogleMap(
mapType: MapType.normal,
zoomControlsEnabled: false,
myLocationEnabled: false,
initialCameraPosition: defaultPosition,
markers: markers,
onMapCreated: (GoogleMapController controller) {
gmc = controller; },),), );}
Future<void> childMove(latitude, longitude) async {
gmc.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: new LatLng(latitude, longitude),
tilt: 59,
zoom: 19.151926040649414,)));
setState(() {
Marker marker = markers.firstWhere((marker) =>
marker.markerId.value == "child");
markers.remove(marker);
markers.add(
Marker(markerId: MarkerId("child"), position: LatLng(latitude,
longitude), icon:
BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen),
infoWindow: InfoWindow(title: child.name)),);});}}

 Children:

57 | P a g e
class Children extends StatefulWidget {
@override
State<StatefulWidget> createState() =>ChildrenState();}
class ChildrenState extends State<Children>{
final Stream<QuerySnapshot> stream =
Database.children().orderBy("z_date_created",descending:
false).snapshots();
@override
void initState(){
super.initState();}
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays:[
SystemUiOverlay.top]);
return Scaffold (
body:StreamBuilder<QuerySnapshot>(
stream: stream,
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Center(child:Text("Server error").tr());}
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Container(
height: double.infinity,
child:Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Loading".tr()+"...."),
SizedBox(width: 30,),
CircularProgressIndicator()],));
default:
if(snapshot.hasData &&
snapshot.data!.docs.length==0){
return Center(child:Text("No Children").tr());}
else{
return Container(
child:
ListView.separated(
separatorBuilder:(context,i){
Child child = Child.fromMap(snapshot.data!.docs[i].data() as
Map<String,dynamic>);
if(child.user_id.toString().compareTo(Database.loggedUserId()) == 0) {
return Divider(thickness: 1,
color: MyColors.gray2,
height: 3,); }
else{
return SizedBox.shrink();}},
shrinkWrap: true,
itemCount: snapshot.data!.docs.length,
padding: EdgeInsets.symmetric(vertical: 5),
itemBuilder:(context,i){
Child child =
Child.fromMap(snapshot.data!.docs[i].data() as Map<String,dynamic>);

58 | P a g e
if(child.user_id.toString().compareTo(Database.loggedUserId()) == 0) {
return
Container(
padding:
EdgeInsets.symmetric(vertical: 25),
child: ListTile(
title: Text("${child.name}",
style: TextStyle(
color: Colors.black,
fontSize: 16)),
leading:
Image.network(child.imgUrl),
tileColor: Colors.white,
contentPadding:
EdgeInsets.symmetric(
horizontal: 7),
onTap: () {

Navigator.of(context).pushNamed("child_info",arguments:
{"child":child});},));}
else{
return SizedBox.shrink();}}));
return Text("");}}}));}
static add_child(context){
Navigator.of(context).pushNamed("add_child");
}}

 Home:

59 | P a g e
class Home extends StatefulWidget {
@override
State<StatefulWidget> createState() =>HomeState();}
class HomeState extends State<Home> {
int selectedNav =0;
List<Widget> pages = [Children(),Reports(),Profile()];
var titles = ["My Children","Reports","My Profile"];
@override
void initState() {
super.initState();}
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays:[
SystemUiOverlay.top]);
return Scaffold(
appBar:AppBar(title:
Text("${titles[selectedNav]}".tr(),style:DesignHelper.barTitleStyle),
actions: selectedNav==0?menu1():selectedNav==2?menu2():menu3()
,automaticallyImplyLeading: false),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.white,
selectedItemColor: Theme.of(context).primaryColor,
unselectedItemColor: Colors.grey,
currentIndex: selectedNav,
onTap: (index){
setState(() {
selectedNav = index;});
//Pref.set_navNumber(selectedNav);},
items:[
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: "My Children".tr()),
BottomNavigationBarItem(
icon: Icon(Icons.insert_drive_file),
label: "Reports".tr()),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: "My Profile".tr() ),],),
body:pages.elementAt(selectedNav) );}
menu1() {
return [
IconButton(icon:Icon(Icons.add,color:
Colors.white,),onPressed:(){ChildrenState.add_child(context);}),]; }
menu2() {
return [
PopupMenuButton<int>(
icon: Icon(Icons.language),
itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
new PopupMenuItem<int>(
value: 0, child: new Text('Lang'.tr())), ],
onSelected: (int value) {
switch(value){

case 0:
setState((){
if(context.locale.languageCode ==
Lang.english.languageCode)

60 | P a g e
context.setLocale(Lang.arabic);
else
context.setLocale(Lang.english); });
break;}})
,IconButton(icon:Icon(Icons.power_settings_new,color:
Colors.white,),onPressed:logout),];}
menu3(){ }
logout(){
AwesomeDialog(
context: context,
title: "Do you want to sign out?".tr(),
isDense: true,
btnCancelText: "no".tr(),
btnCancelOnPress: (){},
btnCancelColor: Colors.blue,
btnOkText: "yes".tr(),
btnOkColor: Colors.blue,
dismissOnBackKeyPress: false,
dismissOnTouchOutside: false,
customHeader: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 20),
Icon(Icons.warning,color: Colors.red,size: 55),
],),
btnOkOnPress: (){
Database.logout();
Navigator.pushReplacementNamed(context,"intro");
},
)..show();}}

 Log-In:

61 | P a g e
class Login extends StatefulWidget {
@override
State<StatefulWidget> createState() =>LoginState();}
class LoginState extends State<Login>{
late String email;
late String password;
GlobalKey<FormState> formState = new GlobalKey<FormState>();
submit() async {
var form = formState.currentState;
if(form!.validate()){
form.save();
final ProgressDialog progressDialog = ProgressDialog(
context, isDismissible: false);
progressDialog.style(
message: 'Login'.tr()+"....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet".tr());}
else {
progressDialog.show();
try {
await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: email,
password: password );
progressDialog.hide();
Pref.set_isLogin(true);
Pref.set_email(email);
Navigator.pushReplacementNamed(context, "home");
} on FirebaseAuthException catch (e) {
progressDialog.hide();
FA.showErrorMsg(context, "Invalid email or
password").tr();}}}}
@override
void initState(){
super.initState();}
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
return Scaffold(
body:Form(key:formState,child:Container(alignment:Alignment.topCenter,w
idth:double.infinity,child:SingleChildScrollView(scrollDirection:
Axis.vertical,child:Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 10),

Container(
alignment: Alignment.topCenter,
padding: EdgeInsets.symmetric(horizontal: 5),

62 | P a g e
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(onPressed:(){
if (Navigator.canPop(context)) {
Navigator.pop(context);
} else {
SystemNavigator.pop();}
}, icon: Icon(Icons.arrow_back),iconSize: 38),
PopupMenuButton<int>(
icon: Icon(Icons.language),
iconSize: 36,
itemBuilder: (BuildContext context) =>
<PopupMenuItem<int>>[
new PopupMenuItem<int>(
value: 0, child: new Text('Lang'.tr())),
],
onSelected: (int value) {
switch(value){
case 0:
setState((){
if(context.locale.languageCode ==
Lang.english.languageCode)
context.setLocale(Lang.arabic);
else
context.setLocale(Lang.english); });
break;}}),]),),
Image(
image: AssetImage('images/logo.png',),
width: 150,
height: 120,),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: MyColors.filedColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: "Email address".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.mail,color:MyColors.filedColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder ),
validator: (text){
if(text!.trim().isEmpty){
return "Email address".tr()+" "+"is
required".tr();}
if(! FA.isEmailValid(text)){
return "Invalid email".tr();}
return null; },
onSaved: (text){email=text.toString();},)),

63 | P a g e
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: MyColors.filedColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.visiblePassword,
obscureText: true,
decoration: InputDecoration(
labelText: "Password".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:Icon(Icons.lock,color:MyColors.filedColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder:
DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Password".tr()+" "+"is required".tr();}
return null; },
onSaved: (text){password=text.toString();},)),
SizedBox(height: 15),
Container(alignment:Alignment.center,
child:TextButton(onPressed: () {
Navigator.of(context).pushNamed("re_password"); },
child:Text("Forgot your
password?".tr(),style:Theme.of(context).textTheme.headline6)),),
SizedBox(height: 25),
SizedBox(width:DesignHelper.buttonWidth2,height:DesignHelper.buttonHeig
ht2,child:
ElevatedButton(onPressed: (){
submit();
}, child: Text("Login").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 15),
],)))));}}

 Profile:

64 | P a g e
class Profile extends StatefulWidget {
@override
State<StatefulWidget> createState() =>ProfileState();}
class ProfileState extends State<Profile>{
late String email;
late String name;
late String phone;
late String address;
late Users user ;
GlobalKey<FormState> formState = new GlobalKey<FormState>();
submit() async {
var form = formState.currentState;
if(form!.validate()){
form.save();
final ProgressDialog progressDialog =
ProgressDialog(context,isDismissible: false);
progressDialog.style(
message: 'Save'.tr()+".....",
messageTextStyle: TextStyle(
color: Theme.of(context).primaryColor, fontSize: 18.0,
fontWeight: FontWeight.normal),
);
if(! await FA.isInternetAvailable()){
FA.showErrorMsg(context,"No internet".tr());}
else {
progressDialog.show();
user.name = name;
user.phone = phone;
user.address = address;
Database.users().doc(user.uid).set(user.toMap()).then((value)
async {
progressDialog.hide();
Fluttertoast.showToast(
msg: "Save done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0 );})
.catchError((error){
progressDialog.hide();
Fluttertoast.showToast(
msg: "Server error".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0
);});}}}
@override
void initState(){
super.initState();}
@override
Widget build(BuildContext context) {

65 | P a g e
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays:[
SystemUiOverlay.top ]);
return Scaffold(
body:FutureBuilder(
future: Database.users().doc(Database.loggedUserId()).get(),
builder: (context,AsyncSnapshot<DocumentSnapshot<Object?>>
snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting: return
Center(child:CircularProgressIndicator());
default:
if (snapshot.hasData) {
user = Users.fromMap(
snapshot.data!.data() as Map<
String,dynamic>);
return
Form(key:formState,child:Container(alignment:Alignment.topCenter,
width:double.infinity,child:SingleChildScrollView(scrollDirection:
Axis.vertical,child:Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.emailAddress,
readOnly: true,
initialValue: user.email,
decoration: InputDecoration(
labelText: "Email address".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.mail,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Email address".tr()+" "+"is
required".tr();}
if(! FA.isEmailValid(text)){
return "Invalid email".tr();}
return null; },
onSaved: (text){email=text.toString();},)),
SizedBox(height: 25),

Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(

66 | P a g e
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
inputFormatters:
[FilteringTextInputFormatter.allow(RegExp("[a-zA-Z\\s]"))],
keyboardType: TextInputType.name,
initialValue: user.name,
decoration: InputDecoration(
labelText: "Full name".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.person,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Full name".tr()+" "+"is required".tr();}
return null; },
onSaved: (text){name=text.toString();},)),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.number,
initialValue: user.phone,
decoration: InputDecoration(
labelText: "Phone number".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.person,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Phone number".tr()+" "+"is required".tr();}
if(text.length != 10){
return "Phone number must 10 numbers".tr();}
return null; },
onSaved: (text){phone=text.toString();},)),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),

child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.streetAddress,

67 | P a g e
initialValue: user.address,
decoration: InputDecoration(
labelText: "Address".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.mail,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder
),
validator: (text){
if(text!.trim().isEmpty){
return "Address".tr()+" "+"is required".tr();}
return null; },
onSaved: (text){address=text.toString();},)),
SizedBox(height: 45),
SizedBox(width:DesignHelper.buttonWidth,height:DesignHelper.buttonHeigh
t,child:
ElevatedButton(onPressed: (){
submit();
}, child: Text("Save").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 60), ],)) ));}
else{
return SizedBox.shrink(); }}}));}}

 Register:

68 | P a g e
class Register extends StatefulWidget {
@override
State<StatefulWidget> createState() =>RegisterState();}
class RegisterState extends State<Register>{
late String email;
late String password;
final TextEditingController passwordEditing =
TextEditingController();
late String name;
late String phone;
late String address;
GlobalKey<FormState> formState = new GlobalKey<FormState>();
submit() async {
var form = formState.currentState;
if(form!.validate()){
form.save();
final ProgressDialog progressDialog =
ProgressDialog(context,isDismissible: false);
progressDialog.style(
message: 'Register'.tr()+".....",
messageTextStyle: TextStyle(
color: Theme.of(context).primaryColor, fontSize: 18.0,
fontWeight: FontWeight.normal),);
if(! await FA.isInternetAvailable()){
FA.showErrorMsg(context,"No internet".tr());}
else {
progressDialog.show();
try {
await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: email,
password: password);
Users user = new
Users(Database.loggedUserId(),email,password,name,phone,address);
Database.users().doc(Database.loggedUserId()).set(user.toMap()).then((v
alue) async {
progressDialog.hide();
Pref.set_isLogin(true);
Pref.set_email(email);
Navigator.pushReplacementNamed(context,"home");
}).catchError((error) {
progressDialog.hide();
FA.showErrorMsg(context,"Server error".tr());});
} on FirebaseAuthException catch (e) {
progressDialog.hide();
if (e.code == 'email-already-in-use') {
FA.showErrorMsg(context,
"Email already exists".tr());}
else {
FA.showErrorMsg(context,
"Server error".tr());}

} catch (e) {
progressDialog.hide();
FA.showErrorMsg(context,e.toString());}}}}
@override

69 | P a g e
void initState(){
super.initState();}
@override
Widget build(BuildContext context){
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
return Scaffold(
body:Form(key:formState,child:Container(alignment:Alignment.topCenter,w
idth:double.infinity,child:SingleChildScrollView(scrollDirection:
Axis.vertical,child:Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 10),
Container(
alignment: Alignment.topCenter,
padding: EdgeInsets.symmetric(horizontal: 5),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(onPressed:(){
if (Navigator.canPop(context)) {
Navigator.pop(context);
} else {
SystemNavigator.pop();
}
}, icon: Icon(Icons.arrow_back),iconSize: 38),
PopupMenuButton<int>(
icon: Icon(Icons.language),
iconSize: 36,
itemBuilder: (BuildContext context) =>
<PopupMenuItem<int>>[
new PopupMenuItem<int>(
value: 0, child: new Text('Lang'.tr())),
],
onSelected: (int value) {
switch(value){
case 0:
setState((){
if(context.locale.languageCode ==
Lang.english.languageCode)
context.setLocale(Lang.arabic);
else
context.setLocale(Lang.english); });
break; } }),]),),
Container(
margin: EdgeInsets.only(left: 22),
child:Image(
image: AssetImage('images/logo.png',),
width: 140,
height: 120,)),

SizedBox(height: 15),
Container(
child: Text("SIGN UP".tr(),style: TextStyle(fontSize:
26,fontWeight:FontWeight.bold,color:MyColors.gray))),

70 | P a g e
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: "Email address".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.mail,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder
), validator: (text){
if(text!.trim().isEmpty){
return "Email address".tr()+" "+"is
required".tr();}
if(! FA.isEmailValid(text)){
return "Invalid email".tr();}
return null; },
onSaved: (text){email=text.toString();},)),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.visiblePassword,
obscureText: true,
controller: passwordEditing,
decoration: InputDecoration(
labelText: "Password".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.lock,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Password".tr()+" "+"is required".tr();}
if(text.length <8){
return "Password must be equal or grater than

8".tr();}
return null; },
onSaved: (text){password=text.toString();},)),
SizedBox(height: 25),
Container(

71 | P a g e
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.visiblePassword,
obscureText: true,//‫نجوم وضع‬
decoration: InputDecoration(
labelText: "Re-Password".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.lock,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Re-Password".tr()+" "+"is required".tr();}
if(text.compareTo(passwordEditing.text) != 0){
return "Password not match".tr();}
return null; },)),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
inputFormatters:
[FilteringTextInputFormatter.allow(RegExp("[a-zA-Z\\s]"))],
keyboardType: TextInputType.name,
decoration: InputDecoration(
labelText: "Full name".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.person,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Full name".tr()+" "+"is required".tr();}
return null; },
onSaved: (text){name=text.toString();},)),
SizedBox(height: 25),

Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.number,

72 | P a g e
decoration: InputDecoration(
labelText: "Phone number".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.person,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder),
validator: (text){
if(text!.trim().isEmpty){
return "Phone number".tr()+" "+"is required".tr();}
if(text.length != 10){
return "Phone number must 10 numbers".tr();}
return null; },
onSaved: (text){phone=text.toString();},)),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.streetAddress,
decoration: InputDecoration(
labelText: "Address".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.mail,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder
), validator: (text){
if(text!.trim().isEmpty){
return "Address".tr()+" "+"is required".tr();}
return null; },
onSaved: (text){address=text.toString();},)),
SizedBox(height: 45),
SizedBox(width:DesignHelper.buttonWidth,height:DesignHelper.buttonHeigh
t,child:
ElevatedButton(onPressed: (){
submit();
}, child: Text("Register").tr(),
style: DesignHelper.buttonStyle,)),
SizedBox(height: 60),],))))); }}

 Recover Password:

73 | P a g e
class RecoverPassword extends StatefulWidget {
@override
State<StatefulWidget> createState() =>RecoverPasswordState();}
class RecoverPasswordState extends State<RecoverPassword>{
late String email;
late String password;
GlobalKey<FormState> formState = new GlobalKey<FormState>();

submit() async {
var form = formState.currentState;
if(form!.validate()){
form.save();
final ProgressDialog progressDialog = ProgressDialog(
context, isDismissible: false);
progressDialog.style(
message: 'Recover'.tr()+"....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal), );
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet".tr()); }
else {
progressDialog.show();
try {
await FirebaseAuth.instance
.sendPasswordResetEmail(
email: email, );
await progressDialog.hide();
Fluttertoast.showToast(
msg: "Password recovery has been sent to your email".tr(),
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 3,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 16.0 );
Navigator.pop(context);
} on FirebaseAuthException catch (e) {
progressDialog.hide();
FA.showErrorMsg(context,
"User not found".tr());}}}}
@override
void initState(){
super.initState();}
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
return Scaffold(

body:Form(key:formState,child:Container(alignment:Alignment.topCenter,w
idth:double.infinity,child:SingleChildScrollView(scrollDirection:
Axis.vertical,child:Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,

74 | P a g e
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 10),
Container(
alignment: Alignment.topCenter,
padding: EdgeInsets.symmetric(horizontal: 5),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(onPressed:(){
if (Navigator.canPop(context)) {
Navigator.pop(context);
} else {
SystemNavigator.pop();}
}, icon: Icon(Icons.arrow_back),iconSize: 38),
PopupMenuButton<int>(
icon: Icon(Icons.language),
iconSize: 36,
itemBuilder: (BuildContext context) =>
<PopupMenuItem<int>>[
new PopupMenuItem<int>(
value: 0, child: new Text('Lang'.tr())),],
onSelected: (int value) {
switch(value){
case 0:
setState((){
if(context.locale.languageCode ==
Lang.english.languageCode)
context.setLocale(Lang.arabic);
else
context.setLocale(Lang.english); });
break; }}), ]),),
Container(
margin: EdgeInsets.only(left: 22),
child:Image(
image: AssetImage('images/logo.png',),
width: 140,
height: 120,)),
SizedBox(height: 35),
Container(
child: Text("Recover Password",style:
TextStyle(fontSize:
24,fontWeight:FontWeight.bold,color:MyColors.gray)).tr()),
SizedBox(height: 30),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: Theme.of(context).primaryColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.emailAddress,

decoration: InputDecoration(
labelText: "Email address".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:

75 | P a g e
Icon(Icons.mail,color:Theme.of(context).primaryColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder
),validator: (text){
if(text!.trim().isEmpty){
return "Email address".tr()+" "+"is
required".tr();}
if(! FA.isEmailValid(text)){
return "Invalid email".tr();}
return null; },
onSaved: (text){email=text.toString();},)),
SizedBox(height: 30),
SizedBox(width:DesignHelper.buttonWidth,height:DesignHelper.buttonHeigh
t,child:
ElevatedButton(onPressed: (){
submit();
}, child: Text("Recover").tr(),
style: DesignHelper.buttonStyle,)),
SizedBox(height: 15), ],))))); }}

 Report Info:
class ReportInfo extends StatefulWidget {

@override

76 | P a g e
State<StatefulWidget> createState() =>ReportInfoState();
}

class ReportInfoState extends State<ReportInfo>{

late Child child;


late Report report;
late String number;

@override
void initState(){
super.initState();
}

@override
Widget build(BuildContext context) {
final Map<String, Object> receivedData =
ModalRoute.of(context)!.settings.arguments as Map<String, Object> ;
child = receivedData['child'] as Child;
report = receivedData['report'] as Report;
number = receivedData['number'] as String;
return Scaffold(
appBar: AppBar(title: Text("Report Info".tr(),style:
DesignHelper.barTitleStyle),actions:menu1()),

body:Container(alignment:Alignment.topCenter,width:double.infinity,chil
d:SingleChildScrollView(scrollDirection: Axis.vertical,child:Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
Image.network(
child.imgUrl,
width: 200,
height: 150,
),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Text("#"+"Report".tr()+" ${number}",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 18)),
),

SizedBox(height: 20),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text("Child name".tr()+" : ",
style: TextStyle(
color: Colors.black,

77 | P a g e
fontWeight: FontWeight.bold,
fontSize: 17)),
Text("${child.name}",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
fontSize: 17))]),
),
SizedBox(height: 20),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text("Child ID".tr()+" : ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 17)),
Text("${child.child_id}",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
fontSize: 17))]),
),
SizedBox(height: 20),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text("Date".tr()+" : ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 17)),
Text("${report.date}",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
fontSize: 17))]),
),

SizedBox(height: 20),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text("Time".tr()+" : ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 17)),
Text("${report.time}",
style: TextStyle(

78 | P a g e
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
fontSize: 17))]),
),
SizedBox(height: 20),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:Column(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text("Report content".tr()+" : ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 17)),
SizedBox(height: 10,),
Text("${report.content}",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontSize: 18))]),
),
SizedBox(height: 20),
]))));
}

menu1() {
return [
IconButton(icon:Icon(Icons.delete,color:
Colors.white,),onPressed:delete_child)
];
}

delete_child(){

AwesomeDialog(
context: context,
title: "Are you sure delete report?".tr(),
isDense: true,
btnCancelText: "no".tr(),
btnCancelOnPress: (){},
btnCancelColor: Colors.blue,
btnOkText: "yes".tr(),
btnOkColor: Colors.blue,
dismissOnBackKeyPress: false,
dismissOnTouchOutside: false,
customHeader: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 20),
Icon(Icons.warning,color: Colors.red,size: 55),
],),
btnOkOnPress: (){
delete();
},
)..show();
}

79 | P a g e
delete() async {
final ProgressDialog progressDialog = ProgressDialog(
context, isDismissible: false);
progressDialog.style(
message: 'Delete report'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),
);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");
}
else {
progressDialog.show();
Database.report().doc(report.report_id).delete().then((value){
progressDialog.hide();
Fluttertoast.showToast(
msg: "Delete done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0
);
if(Navigator.canPop(context)){
Navigator.pop(context);
}
else{
SystemNavigator.pop();
}
}).catchError((error) async {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
});
}
}

 Reports:

class Reports extends StatefulWidget {


@override
State<StatefulWidget> createState() =>ReportsState();

80 | P a g e
}

class ReportsState extends State<Reports>{

final Stream<QuerySnapshot> stream =


Database.report().orderBy("z_date_created",descending:
true).snapshots();

@override
void initState(){
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body:StreamBuilder<QuerySnapshot>(
stream: stream,
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Center(child:Text("Server error").tr());
}
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Container(
height: double.infinity,
child:Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Loading".tr()),
SizedBox(width: 30,),
CircularProgressIndicator()
],
));
default:
if(snapshot.hasData &&
snapshot.data!.docs.length==0){
return Center(child:Text("No Reports".tr()));
}
else{
return Container(
child:
ListView.separated(
separatorBuilder:(context,i){

Report report = Report.fromMap(snapshot.data!.docs[i].data() as


Map<String,dynamic>);

if(report.user_id.toString().compareTo(Database.loggedUserId()) == 0) {
return Divider(thickness: 1,
color: MyColors.gray2,
height: 3,);
}

81 | P a g e
else{
return SizedBox.shrink();
}
},
shrinkWrap: true,
itemCount: snapshot.data!.docs.length,
padding: EdgeInsets.symmetric(vertical: 5),
itemBuilder:(context,i) {
Report report =
Report.fromMap(snapshot.data!.docs[i].data() as Map<String,dynamic>);

if(report.user_id.toString().compareTo(Database.loggedUserId()) == 0) {
return Container(child: FutureBuilder(
future:
Database.children().doc(report.child_id).get(),
builder:
(context,AsyncSnapshot<DocumentSnapshot<Object?>> snapshot) {
if (snapshot.hasData) {
Child child = Child.fromMap(
snapshot.data!.data() as
Map<
String,
dynamic>);

return ListTile(
title:
Text("#"+"Report".tr()+" "+(i+1).toString(),
style: TextStyle(
color: Colors.black,
fontSize: 16)),
trailing: Column(
mainAxisSize:
MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,

children:[Text(report.date,
style: TextStyle(
color:
MyColors.primary,
fontWeight:
FontWeight

.bold,
fontSize: 12)),
SizedBox(height: 8,),
Text(report.time,
style: TextStyle(
color: MyColors.gray,
fontWeight:
FontWeight
.bold,
fontSize: 12))]) ,
subtitle: Container(

82 | P a g e
padding:
EdgeInsets.only(top: 5),
child:
Text("Child".tr()+":
"+child.name,
style: TextStyle(
color:
MyColors.gray,
fontWeight:
FontWeight
.bold,
fontSize: 14))),
leading: ImageIcon(
AssetImage(

"images/file_logo.png"),
size: 47, color: Theme
.of(context)
.primaryColor),
tileColor: Colors.white,
contentPadding:
EdgeInsets.symmetric(
horizontal: 7),

onTap: () {

Navigator.of(context).pushNamed(
"report_info",
arguments: {
"child": child,
"report":report,

"number":(i+1).toString(),
});
},
);
} else {
return SizedBox.shrink();
}

}));
} else{
return SizedBox.shrink();
} }));
return Text("");}}})); }}

 Send Report:

class SendReport extends StatefulWidget {

@override

83 | P a g e
State<StatefulWidget> createState() =>SendReportState();
}

class SendReportState extends State<SendReport> {


late String content;
GlobalKey<FormState> formState = new GlobalKey<FormState>();
late Child child;

submit() async {
var form = formState.currentState;
if (form!.validate()) {
form.save();

final ProgressDialog progressDialog = ProgressDialog(


context, isDismissible: false);
progressDialog.style(
message: 'Send'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),
);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");
}
else {
progressDialog.show();
String report_id = Database
.report()
.doc()
.id;
Report report = new Report(
report_id, child.child_id, content,
Database.loggedUserId());

Database.report().doc(report_id).set(report.toMap()).then((value) {
progressDialog.hide();
Fluttertoast.showToast(
msg: "Send done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0
);

if (Navigator.canPop(context)) {
Navigator.pop(context);

}
else {
SystemNavigator.pop();
}

84 | P a g e
}).catchError((error) {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
});
}
}
}

@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays:
[
SystemUiOverlay.top
]);
final Map<String, Object> receivedData =
ModalRoute.of(context)!.settings.arguments as Map<String, Object> ;
child = receivedData['child'] as Child;
return Scaffold(
appBar: AppBar(title: Text(
"Send report".tr(), style: DesignHelper.barTitleStyle,)),
body: Form(key: formState,
child: Container(alignment: Alignment.topCenter,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.vertical, child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
Container(
height: 6 * 24.0,
margin: EdgeInsets.symmetric(horizontal:
20,vertical: 12),
child: TextFormField(
cursorColor: Theme
.of(context)
.primaryColor,

style: DesignHelper.fieldStyle,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp("[a-zA-Z\\s]"))
],
maxLines: 6,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
labelText: "Report content".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon: Icon(Icons.note, color: Theme

85 | P a g e
.of(context)
.primaryColor),
enabledBorder: DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder:
DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper
.fieldErrorBorder
),
validator: (text) {
if (text!.trim().isEmpty) {
return "Report content".tr() + " " +
"is required".tr();
}

return null;
},
onSaved: (text) {
content = text.toString();
},
)),
SizedBox(height: 35),
SizedBox(width: DesignHelper.buttonWidth2,
height: DesignHelper.buttonHeight2,
child:
ElevatedButton(onPressed: () {
submit();
}, child: Text("Send").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 15),

],))
)));
}
}

 Child Image:
class UpdateChildImage extends StatefulWidget {
@override
State<StatefulWidget> createState() =>UpdateChildImageState();
}

86 | P a g e
class UpdateChildImageState extends State<UpdateChildImage>{

GlobalKey<FormState> formState = new GlobalKey<FormState>();


File image = new File("");
String fileName ="";
late Child child;

submit() async {
var form = formState.currentState;
if (form!.validate()) {
form.save();
if (image.path == "") {
FA.showInfoMsg(context, "Please upload child image".tr());
return;
}

final ProgressDialog progressDialog = ProgressDialog(


context, isDismissible: false);
progressDialog.style(
message: 'Update'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),
);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");
}
else {
progressDialog.show();

FirebaseStorage.instance.refFromURL(child.imgUrl).delete().then((value)
{
Reference reference = FirebaseStorage.instance.ref(

"${Database.loggedUserId()}/${child.child_id}${fileName}");
UploadTask uploadTask = reference.putFile(image);
uploadTask.snapshotEvents.listen((event) async {
if (event.state == TaskState.success) {
String imgUrl = await event.ref.getDownloadURL();

Database.children().doc(child.child_id).update({"imgUrl":imgUrl});
progressDialog.hide();
Fluttertoast.showToast(
msg: "Save done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0
);
back_action();
}

87 | P a g e
}).onError((error) {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
});
}).catchError((error) {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
});
}
}
}

@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [
SystemUiOverlay.top
]);
final Map<String, Object> receivedData =
ModalRoute.of(context)!.settings.arguments as Map<String, Object> ;
child = receivedData['child'] as Child;
return Scaffold(
appBar: AppBar(title: Text(
"Update child".tr(), style: DesignHelper.barTitleStyle,),
leading: new IconButton(
icon: new Icon(Icons.arrow_back),
onPressed: () {
back_action();
})
),

body: new WillPopScope(


onWillPop: back_action,
child:Form(key: formState,
child: Container(alignment: Alignment.topCenter,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.vertical, child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
GestureDetector(child: Container(
margin: EdgeInsets.symmetric(horizontal: 20),
width: double.infinity,
height: 200,
padding: EdgeInsets.symmetric(horizontal:
10),
child: image.path == "" ? Container(
alignment: Alignment.center,
child: Row(mainAxisAlignment:

88 | P a g e
MainAxisAlignment
.center, children: [
Icon(Icons.upload, color:
MyColors.primary,),
Text(
"Upload child image".tr(), style:
TextStyle(
color: MyColors.gray,
fontWeight: FontWeight.bold,
fontSize: 18
), textAlign: TextAlign.center)
])) : Image.file(image,
fit: BoxFit.fill
)
), onTap: () async {
FilePickerResult? result = await
FilePicker.platform
.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'png'],
);
if (result != null) {
PlatformFile file = result.files.first;
setState(() {
fileName = file.name;
image = new File(file.path.toString());
});
}
},),

SizedBox(height: 35),
SizedBox(width: DesignHelper.buttonWidth2,
height: DesignHelper.buttonHeight2,
child:
ElevatedButton(onPressed: () {
submit();
}, child: Text("Update").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 15),
],)) )))); }
Future<bool> back_action() async {
Navigator.pushReplacementNamed(context, "child_info",arguments:
{"child":child});
return Future.value(false); }}

 Child Name:
class UpdateChildName extends StatefulWidget {
@override
State<StatefulWidget> createState() =>UpdateChildNameState();
}

89 | P a g e
class UpdateChildNameState extends State<UpdateChildName>{

late String name;


GlobalKey<FormState> formState = new GlobalKey<FormState>();
late Child child;

submit() async {
var form = formState.currentState;
if (form!.validate()) {
form.save();

final ProgressDialog progressDialog = ProgressDialog(


context, isDismissible: false);
progressDialog.style(
message: 'Update'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),
);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");
}
else {
progressDialog.show();

Database.children().doc(child.child_id).update({"name":name});
progressDialog.hide();
Fluttertoast.showToast(
msg: "Save done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0
);
back_action();
}
}
}

@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [
SystemUiOverlay.top
]);

90 | P a g e
final Map<String, Object> receivedData =
ModalRoute.of(context)!.settings.arguments as Map<String, Object> ;
child = receivedData['child'] as Child;
return Scaffold(
appBar: AppBar(title: Text(
"Update child".tr(), style: DesignHelper.barTitleStyle,),
leading: new IconButton(
icon: new Icon(Icons.arrow_back),
onPressed: () {
back_action();
})
),
body:new WillPopScope(
onWillPop: back_action,
child: Form(key: formState,
child: Container(alignment: Alignment.topCenter,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.vertical, child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child: TextFormField(
cursorColor: Theme
.of(context)
.primaryColor,
style: DesignHelper.fieldStyle,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp("[a-zA-Z\\s]"))
],
keyboardType: TextInputType.name,
initialValue: child.name,
decoration: InputDecoration(
labelText: "Child name".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle:

DesignHelper.fieldErrorStyle,
prefixIcon: Icon(Icons.person, color:
Theme
.of(context)
.primaryColor),

enabledBorder:
DesignHelper.fieldBorder,
focusedBorder:
DesignHelper.fieldBorder,
disabledBorder:
DesignHelper.fieldBorder,
errorBorder:
DesignHelper.fieldErrorBorder,

91 | P a g e
focusedErrorBorder: DesignHelper
.fieldErrorBorder
),
validator: (text) {
if (text!.trim().isEmpty) {
return "Child name".tr() + " " +
"is required".tr();
}

return null;
},
onSaved: (text) {
name = text.toString();
},
)),
SizedBox(height: 35),
SizedBox(width: DesignHelper.buttonWidth2,
height: DesignHelper.buttonHeight2,
child:
ElevatedButton(onPressed: () {
submit();
}, child: Text("Save").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 15),

],))
))));
}

Future<bool> back_action() async {


Navigator.pushReplacementNamed(context, "child_info",arguments:
{"child":child});
return Future.value(false);
}

 Update Child Image


class UpdateChildImage extends StatefulWidget {
@override
State<StatefulWidget> createState() =>UpdateChildImageState();
}

92 | P a g e
class UpdateChildImageState extends State<UpdateChildImage>{

GlobalKey<FormState> formState = new GlobalKey<FormState>();


File image = new File("");
String fileName ="";
late Child child;

submit() async {
var form = formState.currentState;
if (form!.validate()) {
form.save();
if (image.path == "") {
FA.showInfoMsg(context, "Please upload child image".tr());
return;
}

final ProgressDialog progressDialog = ProgressDialog(


context, isDismissible: false);
progressDialog.style(
message: 'Update'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),
);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");
}
else {
progressDialog.show();

FirebaseStorage.instance.refFromURL(child.imgUrl).delete().then((value)
{
Reference reference = FirebaseStorage.instance.ref(

"${Database.loggedUserId()}/${child.child_id}${fileName}");
UploadTask uploadTask = reference.putFile(image);
uploadTask.snapshotEvents.listen((event) async {
if (event.state == TaskState.success) {
String imgUrl = await event.ref.getDownloadURL();

Database.children().doc(child.child_id).update({"imgUrl":imgUrl});
progressDialog.hide();
Fluttertoast.showToast(
msg: "Save done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0
);
back_action(); }
}).onError((error) {
progressDialog.hide();

93 | P a g e
FA.showErrorMsg(context, "Server error".tr());
});
}).catchError((error) {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());
}); }}}
@override
void initState() {
super.initState();}
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [
SystemUiOverlay.top
]);
final Map<String, Object> receivedData =
ModalRoute.of(context)!.settings.arguments as Map<String, Object> ;
child = receivedData['child'] as Child;
return Scaffold(
appBar: AppBar(title: Text(
"Update child".tr(), style: DesignHelper.barTitleStyle,),
leading: new IconButton(
icon: new Icon(Icons.arrow_back),
onPressed: () {
back_action();
})),
body: new WillPopScope(
onWillPop: back_action,
child:Form(key: formState,
child: Container(alignment: Alignment.topCenter,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.vertical, child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
GestureDetector(child: Container(
margin: EdgeInsets.symmetric(horizontal: 20),
width: double.infinity,
height: 200,
padding: EdgeInsets.symmetric(horizontal:
10),
child: image.path == "" ? Container(
alignment: Alignment.center,
child: Row(mainAxisAlignment:
MainAxisAlignment
.center, children: [
Icon(Icons.upload, color:
MyColors.primary,),
Text(
"Upload child image".tr(), style:
TextStyle(
color: MyColors.gray,
fontWeight: FontWeight.bold,
fontSize: 18

94 | P a g e
), textAlign: TextAlign.center)
])) : Image.file(image,
fit: BoxFit.fill
)
), onTap: () async {
FilePickerResult? result = await
FilePicker.platform
.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'png'],
);
if (result != null) {
PlatformFile file = result.files.first;
setState(() {
fileName = file.name;
image = new File(file.path.toString());
});
}
},),
SizedBox(height: 35),
SizedBox(width: DesignHelper.buttonWidth2,
height: DesignHelper.buttonHeight2,
child:
ElevatedButton(onPressed: () {
submit();
}, child: Text("Update").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 15),

],))
))));
}

Future<bool> back_action() async {


Navigator.pushReplacementNamed(context, "child_info",arguments:
{"child":child});
return Future.value(false);
}

 Update Child Name

class UpdateChildName extends StatefulWidget {


@override
State<StatefulWidget> createState() =>UpdateChildNameState();
}

95 | P a g e
class UpdateChildNameState extends State<UpdateChildName>{
late String name;
GlobalKey<FormState> formState = new GlobalKey<FormState>();
late Child child;
submit() async {
var form = formState.currentState;
if (form!.validate()) {
form.save();
final ProgressDialog progressDialog = ProgressDialog(
context, isDismissible: false);
progressDialog.style(
message: 'Update'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet");} else {
progressDialog.show();
Database.children().doc(child.child_id).update({"name":name});
progressDialog.hide();
Fluttertoast.showToast(
msg: "Save done".tr(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: MyColors.primary,
textColor: Colors.white,
fontSize: 15.0);back_action();}}}
@override
void initState() {
super.initState();}
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [
SystemUiOverlay.top]);
final Map<String, Object> receivedData =
ModalRoute.of(context)!.settings.arguments as Map<String, Object> ;
child = receivedData['child'] as Child;
return Scaffold(
appBar: AppBar(title: Text(
"Update child".tr(), style:
DesignHelper.barTitleStyle,),
leading: new IconButton(
icon: new Icon(Icons.arrow_back),
onPressed: () {
back_action();})),
body:new WillPopScope(
onWillPop: back_action,
child: Form(key: formState,
child: Container(alignment: Alignment.topCenter,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.vertical, child: Column(
mainAxisSize: MainAxisSize.max,

96 | P a g e
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 30),
Container(margin:
EdgeInsets.symmetric(horizontal:20),
child: TextFormField(
cursorColor: Theme
.of(context)
.primaryColor,
style: DesignHelper.fieldStyle,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp("[a-zA-Z\\s]"))],
keyboardType: TextInputType.name,
initialValue: child.name,
decoration: InputDecoration(
labelText: "Child name".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle:
DesignHelper.fieldErrorStyle,
prefixIcon: Icon(Icons.person,
color: Theme
.of(context)
.primaryColor),
enabledBorder:
DesignHelper.fieldBorder,
focusedBorder:
DesignHelper.fieldBorder,
disabledBorder:
DesignHelper.fieldBorder,
errorBorder:
DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper
.fieldErrorBorder),
validator: (text) {
if (text!.trim().isEmpty) {
return "Child name".tr() + " " +
"is required".tr();}
return null;},
onSaved: (text) {
name = text.toString();},)),
SizedBox(height: 35),
SizedBox(width: DesignHelper.buttonWidth2,
height: DesignHelper.buttonHeight2,
child:

ElevatedButton(onPressed: () {
submit();}, child: Text("Save").tr(),
style: DesignHelper.buttonStyle,)),
SizedBox(height: 15),],))))));}
Future<bool> back_action() async {
Navigator.pushReplacementNamed(context, "child_info",arguments:
{"child":child});
return Future.value(false);}

97 | P a g e
 Main Dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await EasyLocalization.ensureInitialized();
Pref.pref = await SharedPreferences.getInstance();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {runApp(

98 | P a g e
EasyLocalization(
supportedLocales: [Lang.english,Lang.arabic],
path: 'assets/translations',
fallbackLocale: Lang.english,
startLocale: Lang.english ,
child: MyApp() ), );});}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
debugShowCheckedModeBanner: false,
home:Splash(),
routes: {
"splash": (context) => Splash(),
"login": (context) => Login(),
"register": (context) => Register(),
"re_password": (context) => RecoverPassword(),
"home": (context) => Home(),
"intro": (context) => Intro(),
"child_info": (context) => ChildInfo(),
"child_map": (context) => ChildMap(),
"children": (context) => Children(),
"add_child": (context) => AddChild(),
"update_child_name": (context) => UpdateChildName(),
"send_report": (context) => SendReport(),
"update_child_image": (context) => UpdateChildImage(),
"report_info": (context) => ReportInfo(),},
theme: ThemeData(
primaryColor: MyColors.primary,
primarySwatch:
MaterialColor(MyColors.primarySwatch,MyColors.color),
colorScheme: ColorScheme.light(
primary: MyColors.primary,
secondary: MyColors.primary,),
fontFamily: (Lang.isArabic(context.locale))?"cairo":"",
unselectedWidgetColor: MyColors.primary,//radio
canvasColor: Colors.white,
brightness: Brightness.light,
textTheme:TextTheme(
subtitle1: TextStyle(

color: MyColors.gray,
fontSize: 15,
fontWeight: FontWeight.bold,
),
subtitle2: TextStyle(
color: MyColors.primary,
fontSize: 17,
fontWeight: FontWeight.bold,
),
headline6:TextStyle(
color: MyColors.primary,
fontFamily: "cairo_bold",

99 | P a g e
fontSize: 15,

),
bodyText2: TextStyle(
color: Colors.black,
)),
),);}}

5.5 Source code for (Child Application):


 Child Map:

class ChildMap extends StatefulWidget {


@override
State<StatefulWidget> createState() =>ChildMapState();}
class ChildMapState extends State<ChildMap> {

100 | P a g e
late GoogleMapController gmc;
var child_id = Pref.get_child();
late LatLng current_latLang;
Set<Marker> markers = {};
late StreamSubscription<Position> ps;
static final CameraPosition defaultPosition = CameraPosition(
target: LatLng(0, 0),
tilt: 59,
zoom: 19.151926040649414,
);
void mapSettings() async {
Position position = await Geolocator.getCurrentPosition();
setState(() {
current_latLang = LatLng(position.latitude, position.longitude);
gmc.moveCamera(CameraUpdate.newLatLng(current_latLang));

Marker m1 = Marker(markerId: MarkerId("child"),


position: current_latLang
,
icon:
BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen)
);
markers.add(m1);});}
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
mapSettings();});
ps = Geolocator.getPositionStream().listen(
(Position pos) {
var lat = pos.latitude;
var lng = pos.longitude;
childMove(lat,lng);

Database.children().doc(child_id).update({"lat":lat,"lng":lng});});}
@override
void dispose() {
Database.children().doc(child_id).update({"is_online":false});
super.dispose();}
Future<bool> _onWillPop() async {
return (await showDialog(
context: context,
builder: (context) => new AlertDialog(
content: new Text("Do you want to sign out?".tr(),
style:TextStyle(fontSize: 17,color:Colors.black)),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: new Text('no'.tr(),
style:TextStyle(fontSize:
17,color:MyColors.primary)),),
TextButton(
onPressed: () {

Database.children().doc(child_id).update({"is_online":false});
Database.logout();
Navigator.pushReplacementNamed(context,"login");

101 | P a g e
},
child: new Text('yes'.tr(),
style:TextStyle(fontSize:
17,color:MyColors.primary)),),],),
)) ?? false;}@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays:
[
SystemUiOverlay.top
]);
return new WillPopScope(
onWillPop: _onWillPop,
child: new Scaffold(
appBar: AppBar(title: Text(
"Child".tr()+" - "+child_id, style: DesignHelper.barTitleStyle,
), actions: menu1()),
body: Container(
child: GoogleMap(
mapType: MapType.normal,
zoomControlsEnabled: false,
myLocationEnabled: false,
initialCameraPosition: defaultPosition,
markers: markers,
onMapCreated: (GoogleMapController controller) {
gmc = controller;
},),),));}
Future<void> childMove(latitude, longitude) async {
gmc.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: new LatLng(latitude, longitude),
tilt: 59,
zoom: 19.151926040649414,
)));
setState(() {
Marker marker = markers.firstWhere((marker) =>
marker.markerId.value == "child");
markers.remove(marker);
markers.add(
Marker(markerId: MarkerId("child"), position: LatLng(latitude,
longitude),
icon:
BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen)
),);});}

menu1() {
return [
PopupMenuButton<int>(
icon: Icon(Icons.language),
itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
new PopupMenuItem<int>(
value: 0, child: new Text('Lang'.tr())),],
onSelected: (int value) {
switch(value){
case 0:
setState((){
if(context.locale.languageCode ==
Lang.english.languageCode)

102 | P a g e
context.setLocale(Lang.arabic);
else
context.setLocale(Lang.english);
});
break;}})
,IconButton(icon:Icon(Icons.power_settings_new,color:
Colors.white,),onPressed:logout),];}
logout(){
AwesomeDialog(
context: context,
title: "Do you want to sign out?".tr(),
isDense: true,
btnCancelText: "no".tr(),
btnCancelOnPress: (){},
btnCancelColor: Colors.blue,
btnOkText: "yes".tr(),
btnOkColor: Colors.blue,
dismissOnBackKeyPress: false,
dismissOnTouchOutside: false,
customHeader: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 20),
Icon(Icons.warning,color: Colors.red,size: 55),
],),
btnOkOnPress: (){
Database.children().doc(child_id).update({"is_online":false});
Database.logout();
Navigator.pushReplacementNamed(context,"login");
},
)..show();
}
}

 Child Log-In:

class Login extends StatefulWidget {


@override
State<StatefulWidget> createState() =>LoginState();
}

class LoginState extends State<Login>{

103 | P a g e
late String child_id;
GlobalKey<FormState> formState = new GlobalKey<FormState>();

submit() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
FA.showErrorMsg(context, "Please enable location".tr());}
else {
LocationPermission permission;
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
FA.showErrorMsg(context, "Please grant storage
permission").tr();
return;
}
return;
}
if (permission == LocationPermission.deniedForever) {
FA.showInfoMsg(
context, "Please grant location permission from
settings").tr();
openAppSettings();
return;
}
}

var form = formState.currentState;


if (form!.validate()) {
form.save();

final ProgressDialog progressDialog = ProgressDialog(


context, isDismissible: false);
progressDialog.style(
message: 'Login'.tr() + "....",
messageTextStyle: TextStyle(
color: Theme
.of(context)
.primaryColor, fontSize: 18.0, fontWeight:
FontWeight.normal),
);
if (!await FA.isInternetAvailable()) {
FA.showErrorMsg(context, "No internet".tr());}
else {
progressDialog.show();
Database.children().doc(child_id).get().then((snapshot) async {
if (!snapshot.exists) {
progressDialog.hide();
FA.showErrorMsg(context, "Child ID not exist".tr());
}
else {
progressDialog.hide();
Pref.set_isLogin(true);
Pref.set_child(child_id);

104 | P a g e
Database.children().doc(child_id).update({"is_online":true});
Navigator.of(context).pushReplacementNamed("child_map");

}}).catchError((error) {
progressDialog.hide();
FA.showErrorMsg(context, "Server error".tr());

});
}
}
}
@override
void initState(){
super.initState();
}
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
return Scaffold(

body:Form(key:formState,child:Container(alignment:Alignment.topCenter,w
idth:double.infinity,child:SingleChildScrollView(scrollDirection:
Axis.vertical,child:Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 10),
Container(
alignment: Alignment.topCenter,
padding: EdgeInsets.symmetric(horizontal: 5),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(""),
PopupMenuButton<int>(
icon:
Icon(Icons.language,color:MyColors.primary),
iconSize: 36,

itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[


new PopupMenuItem<int>(
value: 0, child: new Text('Lang'.tr())),
],
onSelected: (int value) {
switch(value){
case 0:
setState((){
if(context.locale.languageCode ==
Lang.english.languageCode)
context.setLocale(Lang.arabic);
else
context.setLocale(Lang.english);
});
break;
} }), ]), ),
SizedBox(height: 25),

105 | P a g e
Image(
image: AssetImage('images/logo.png',),
width: 150,
height: 120,
),
SizedBox(height: 25),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child:TextFormField(
cursorColor: MyColors.filedColor,
style: DesignHelper.fieldStyle,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: "Child ID".tr(),
labelStyle: DesignHelper.fieldStyle,
errorStyle: DesignHelper.fieldErrorStyle,
prefixIcon:
Icon(Icons.perm_identity,color:MyColors.filedColor),
enabledBorder:DesignHelper.fieldBorder,
focusedBorder: DesignHelper.fieldBorder,
disabledBorder: DesignHelper.fieldBorder,
errorBorder: DesignHelper.fieldErrorBorder,
focusedErrorBorder: DesignHelper.fieldErrorBorder
),
validator: (text){
if(text!.trim().isEmpty){
return "Child ID".tr()+" "+"is required".tr();
}
if(text.length != 6){
return "Child ID must 6 numbers".tr();
}
return null;
},
onSaved: (text){child_id=text.toString();},
)),
SizedBox(height: 25),

SizedBox(width:DesignHelper.buttonWidth2,height:DesignHelper.buttonHeig
ht2,child:
ElevatedButton(onPressed: (){
submit();
}, child: Text("Login").tr(),
style: DesignHelper.buttonStyle,
)),
SizedBox(height: 15),],)) ))); }}

 Child Main Dart:

void main() async {


WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await EasyLocalization.ensureInitialized();
Pref.pref = await SharedPreferences.getInstance();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) { runApp(

106 | P a g e
EasyLocalization(
supportedLocales: [Lang.english,Lang.arabic],
path: 'assets/translations',
fallbackLocale: Lang.english,
startLocale: Lang.english ,
child: MyApp()),);});}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
debugShowCheckedModeBanner: false,
home:Splash(),
routes: {
"splash": (context) => Splash(),
"login": (context) => Login(),
"child_map": (context) => ChildMap(),},
theme: ThemeData(
primaryColor: MyColors.primary,
primarySwatch:
MaterialColor(MyColors.primarySwatch,MyColors.color),
colorScheme: ColorScheme.light(
primary: MyColors.primary,
secondary: MyColors.primary,),
fontFamily: (Lang.isArabic(context.locale))?"cairo":"",
unselectedWidgetColor: MyColors.primary,//radio
canvasColor: Colors.white,
brightness: Brightness.light,
textTheme:TextTheme(
subtitle1: TextStyle(
color: MyColors.gray,
fontSize: 15,
fontWeight: FontWeight.bold,),
subtitle2: TextStyle(
color: MyColors.primary,
fontSize: 17,
fontWeight: FontWeight.bold,),
headline6:TextStyle(
color: MyColors.primary,
fontFamily: "cairo_bold",
fontSize: 15,),
bodyText2: TextStyle( color: Colors.black,)),),);}}

5.6 I/O Screens

Splash Screen (E/A)

107 | P a g e
Figure 5.6: Splash Screen (E/A)

Log-In (E/A)

Figure 5.6: Log-In (E/A)

Sign-Up (E/A)

108 | P a g e
Figure 5.6: Sign-Up (E/A)

Recover Password (E/A)

Figure 5.6: Recover Password (E/A)

Add Child (E/A)

109 | P a g e
Figure 5.6: Add Child (E/A)

Children (E/A)

Figure 5.6: Children (E/A)

Child Information (E/A)

110 | P a g e
Figure 5.6: Child Information (E/A)

Profile (E/A)

Figure 5.6: Profile (E/A)

111 | P a g e
Reports (E/A)

Figure 5.6: Report (E/A)

112 | P a g e
Send Reports (E/A)

Figure 5.6: Send Report (E/A)

Map (E/A)

Figure 5.6: Map (E/A)

113 | P a g e
Chapter 6: Testing

114 | P a g e
6.1 Introduction

System Testing: is a level of testing that validates the complete and fully integrated
software product. The purpose of a system test is to evaluate the end-to-end system
specifications.

6.2 Testing Plan


6.2.1 Testing Strategy

6.2.1.1 Unit Testing


Is a type of software testing where individual units or components
of the software are tested. The purpose is to validate that each unit
of the software code performs as expected. Unit testing is done
during the development (coding phase) of an application by the
developers.[10]

6.2.1.2 Functional Testing


Is a software testing process that validates the software system
against functional requirements. The purpose of functional testing
is to test each functionality of the software application, by
providing apt input, output verification against the functional
requirements.[11]

6.2.1.3 Acceptance Testing


Is a method of software testing where a system is tested for
acceptability. The major aim of this test is to evaluate the
compliance of the system with the business requirements and
assess whether it is acceptable for delivery or not.[12]

6.2.1.4 Test Objective


Provide a prioritized list of verification or validation objectives for
the project. You use this list of objectives to measure testing
progress and verify that testing activity is consistent with project
objectives.[13]

115 | P a g e
6.3 The key function of our application:
6.3.1 Parents:

 Log-In
 Sign-Up
 Recover Password
 Add Child
 Delete Child
 Children
 Child Information
 Profile
 Child Map
 Reports
 Send Reports
 Reports Information
 Home

6.3.2 Child:

 Child Id
 Map

116 | P a g e
6.4 Testing Cases

Actor Parents
Function Name Log-In
Description The parent login when they have an account

Test Test case Expected


Function Input Pass/Fail
Case Objective Result
Entering email
Email:
1 User log-In without email Invalid email Fail
Leena
address
Entering an Email:
email with the leenamenabhi@ Invalid email
2 User log-In Fail
wrong hotmail.com or password
password Password: llllll
Entering
Password: Email address
3 User log-In password Fail
leena123 is required
without email
Error message
Without email (Email and
4 User log-In _
or password Password are Fail
required)
Email:
Entering valid leenamenabhi@ Log-In to the
5 User log-In email and hotmail.com app Pass
password Password: successfully
leena123

117 | P a g e
Actor Parents
Function Name Sign-Up
Description The parent provides the required information

Test Test case Expected


Function Input Pass/Fail
Case Objective Result
Entering email
User Sign- Email:
1 without email Invalid email Fail
Up Leena
address
Password must
User Sign- Entering short
2 Password: leena be equal or Fail
Up Password
greater than 8
Password:
Entering
User Sign- leena123 Password not
3 unmatched Fail
Up Re-password: matched
password
Leena12
Entering a Phone number
User Sign-
4 short phone Phone number: must be 10 Fail
Up
number 055566 number
Email:
leenamenabhi@
hotmail.com
Password:
Entering all the
leena123 Register to the
User Sign- required
5 Full Name: app Pass
Up information
Leena menabhi successfully
correctly
Phone number:
0506835891
Address:
Alyasmeen

118 | P a g e
Actor Parents
Function Name Home Page
Description The parent can view the home page

Test Test case Expected


Function Input Pass/Fail
Case Objective Result
Email:
leenamenabhi@
hotmail.com
Password:
Entering all
leena123
User the required Register to the
1 Full Name:
Sign-Up information app successfully Pass
Leena menabhi
correctly
Phone number:
0506835891
Address:
Alyasmeen
Email:
User log- Entering valid leenamenabhi@
Log-In to the
2 In email and hotmail.com Pass
app successfully
password Password:
leena123

Actor Parents
Function Name Add Child
Description The parent can Add child Name and Picture

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
Not adding Full name is
1 Add Child - Fail
child name required
Error message
Not uploading
2 Add Child - (please upload Fail
child picture
child image)
Adding full
The child is
child name and Leena
3 Add Child added to my Pass
uploading Mohammed
children list
pictures

Actor Parents
119 | P a g e
Function Name My Children
Description The parent can see their children list

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
My There is no Nothing to
1 - Fail
Children child added show
Adding full
The child
child name
My Leena viewed in
2 and Pass
Children Mohammed my children
uploading
list
pictures

Actor Parents
Function Name Child Information
Description The parent views their child information

Test Test case


Function Input Expected Result Pass/Fail
Case Objective
Child Name:
Adding the
There is a Leenamohammed
Child name and
1 child added Child Id: 973626 Pass
Information uploading the
previously Child status:
picture
offline/Online
No child
Child There is no
2 - information will Fail
Information child added
appear

Actor Parents
Function Name Delete Child
Description The parent can delete their children

Test Test case Expected


Function Input Pass/Fail
Case Objective Result
If they did not There is no
1 Delete Child add a child - child member Fail
member to be deleted
Pressing on
Are you sure
If they added a child name
2 Delete Child delete child? Pass
child member choosing to
(yes)
delete the child

120 | P a g e
Actor Parents
Function Name Send Report
Description The parent sends a report if they lost their child

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
Not
Report
Send providing
1 - content is Fail
Report report
required
content
Notification
Providing
Send I have lost my message
2 report Pass
Report child that shows
content
report send

Actor Parents
Function Name Report
Description The parent can view the opened reports

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
Not
No reports
1 Reports opening a - Fail
to view
report
All the
Opening a A list of reports reports will
2 Reports Pass
report is viewed appear in
the report

Actor Parents
Function Name Report Info
Description The parent can view report info

Test Test case


Function Input Expected Result Pass/Fail
Case Objective
Report Not opening
1 - No report info to view Fail
Info a report
The report info will
Opening a
contain the report
Report Opening a report by
2 number, child name, Pass
Info report writing report
id, date, time
content
and report content

121 | P a g e
Actor Parents
Function Name Report Info
Description The parent can view report info

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
Not
No report
1 Report Info opening a - Fail
info to view
report
The report
info will
contain the
Opening a report
Opening a report by number,
2 Report Info Pass
report writing report child name,
content id, date,
time
and report
content

Actor Parents
Function Name My Profile
Description The parent can view their personal information

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
All the
Pressing on
Having an saved
(My profile) in
1 My Profile existing information Pass
the navigation
account has
bar
appeared

122 | P a g e
Actor Parents
Function Name Child Map
Description The parent can view their child location

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
Press the It will not
The child status
1 Child Map track child view child Fail
is offline
button location
The child did
Press the not verify the It will not
2 Child Map track child child id in the view child Fail
button child location
application
The child is
The child
Press the online and has
location will
3 Child Map track child verified the id Pass
be specified
button of the in-child
in map
application

Actor Parents
Function Name Recover Password
Description The parent could recover their password if they forgot it

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
Entering
Recover Recover User not
1 unregistered Fail
Password Password found
email
Password
recovery
Recover Recover Entering
2 has been Pass
Password Password registered email
sent to your
email

123 | P a g e
Actor Parent
Function Name Update child Image
Description The parent can child their child picture

Test case Expected


Test Case Function Input Pass/Fail
Objective Result

The parent Not uploading


Update Please upload
1 wants to change new child Fail
image child image
child image image

The parent
Update uploading new
2 wants to change Save done Pass
image child image
child image

Actor Parent
Function Name Update child Name
Description The parent can change their child name

Test case Expected


Test Case Function Input Pass/Fail
Objective Result

The parent
Update Not typing Child name is
1 wants to change Fail
name child name required
child name

The parent
Update typing child
2 wants to change Save done Pass
name name
child name

124 | P a g e
Actor Child
Function Name Child ID
Description The child enters the verified child id in the parents’ application

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
Entering Child id is
1 Child ID - Fail
Child ID required
Entering child Child id
Entering
2 Child ID id with more must be 6 Fail
Child ID
than 6 numbers number
Child id
Entering Entering wrong
3 Child ID does not Fail
Child ID child id
exist
Entering Entering the Will view
4 Child ID Pass
Child ID correct child id child map

Actor Parent / Child


Function Name Log-Out
Description The parent and child can logout from their account

Test case Expected


Test Case Function Input Pass/Fail
Objective Result
The parent The account
wants to logout Click on logout will get logged
1 Log-Out Pass
from the at sidebar out and back to
account welcome page
The account
The child wants
Click on logout will get logged
2 Log-Out to logout from Pass
at sidebar and back to
the account
child id page

125 | P a g e
6.5 Test Result

After applying all the mentioned tests, our test plan could not find any application
error.

Function Result
Log-In Pass
Sign-Up Pass
Recover Password Pass
Add Child Pass
Children Pass
Child Information Pass
Profile Pass
Child Map Pass
Reports Pass
Send Reports Pass
Reports Info Pass
Home Pass
Delete Child Pass
Child ID Pass
Map Pass

126 | P a g e
Conclusion

127 | P a g e
7.1 Conclusions

Although success is enhanced by cooperation, not every recovery effort is


successful. Despite the best efforts of the family, friends and volunteers, law
enforcement, and the media, some missing children are not recovered alive and the
whereabouts of others remain a mystery to this day. This project proposed the
presence and assistance of missing children to their parents. So, the main concept of
the whole project is to program an application to minimize the percent of missing
children every year and the probability of never come back to their families.

We have developed GEO-localization of lost children using IOT application, the


application will help families with tracking their under-age children.

7.2 Future Work

In our graduation project the system is only used in Saudi Arabia we are hoping that
we can add new features such as:

- Releasing the application to be worldwide

- Add more languages

- Connect the application to a bracelet that can locates child location

128 | P a g e
References

[1] ResearchGate. 2021. [online] Available at:

129 | P a g e
<https://www.researchgate.net/publication/283647124_Missing_children_and_parenta
l_struggle_From_chaos_to_coping> [Accessed 11 April 2021].

[2] Global Missing Children's Network. 2021. Missing Children's Statistics - Global
Missing Children's Network. [online] Available at:
<https://globalmissingkids.org/awareness/missing-children-
statistics/#:~:text=One%20Missing%20Child%20Is%20One%20Too%20Many&text=I
n%20Australia%2C%20an%20estimated%2020%2C000,are%20reported%20missing
%20each%20year.> [Accessed 11 April 2021].

[3] Tutorialspoint.com. 2021. SDLC - Waterfall Model - Tutorialspoint. [online]


Available at: <https://www.tutorialspoint.com/sdlc/sdlc_waterfall_model.htm>
[Accessed 11 April 2021].

[4] Fracttal.com. 2021. The 9 most important applications of the Internet of Things
(IoT). [online] Available at: <https://www.fracttal.com/en/blog/the-9-most-important-
applications-of-the-internet-of-things> [Accessed 11 April 2021].

[5] Eastern Peak - Technology Consulting & Development Company. 2021. IoT
Projects Examples. [online] Available at: <https://easternpeak.com/works/iot/>
[Accessed 11 April 2021].

[6] Eastern Peak - Technology Consulting & Development Company. 2021. IoT
Projects Examples. [online] Available at: <https://easternpeak.com/works/iot/>
[Accessed 11 April 2021].

[7] Apple Support. 2021. Use Find My iPhone on iCloud.com on your computer.
[online] Available at: <https://support.apple.com/en-
gb/guide/icloud/mm6b1aa045/icloud> [Accessed 11 April 2021].

[8] 2021. [online] Available at: <https://www.g2.com/categories/iot-platforms/free>


[Accessed 11 April 2021].

[9] Cirelly, J., 2021. 8 Best IoT Platforms For Business (Paid & Free). [online]
ITPRC. Available at: <https://www.itprc.com/iot-platforms-for-business/> [Accessed
11 April 2021].

130 | P a g e
[10] Guru99. 2021. Unit Testing Tutorial: What is, Types, Tools & Test EXAMPLE.
[online] Available at: <https://www.guru99.com/unit-testing-guide.html> [Accessed 30
November 2021].

[11] ZealousWeb. 2021. Unit Testing Vs Functional Testing: A Guide On Why, What &
How. [online] Available at: <https://www.zealousweb.com/unit-testing-vs-functional-
testing-a-guide-on-why-what-how/> [Accessed 30 November 2021].

[12] GeeksforGeeks. 2021. Acceptance Testing | Software Testing - GeeksforGeeks.


[online] Available at: <https://www.geeksforgeeks.org/acceptance-testing-software-
testing/> [Accessed 30 November 2021].

[13] Docs.oracle.com. 2021. Bookshelf v8.0: Test Objectives. [online] Available at:
<https://docs.oracle.com/cd/B40099_02/books/TestGuide/TestGuide_PlanTesting3.html
> [Accessed 30 November 2021].

131 | P a g e

You might also like