fix: bug fixing on API response

This commit is contained in:
Syaroful 2024-10-23 08:18:30 +07:00
parent bbc4d6a632
commit fa041950c5
39 changed files with 443 additions and 160 deletions

View File

@ -1,5 +1,8 @@
plugins {
id "com.android.application"
// START: FlutterFire Configuration
id 'com.google.gms.google-services'
// END: FlutterFire Configuration
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
@ -24,7 +27,7 @@ android {
applicationId = "com.pis.agrilink_vocpro"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
minSdk = 21
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName

View File

@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "445047869982",
"project_id": "agrilink-vocpro-b37f9",
"storage_bucket": "agrilink-vocpro-b37f9.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:445047869982:android:d40dc2fd624f86a315540f",
"android_client_info": {
"package_name": "com.pis.agrilink_vocpro"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyCB8i2dE3Oc0kTNtVPw_qSz-T8gPYNjxFk"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View File

@ -19,6 +19,9 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
// END: FlutterFire Configuration
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}

View File

@ -0,0 +1,13 @@
{
"type": "service_account",
"project_id": "agrilink-vocpro-b37f9",
"private_key_id": "e6565344e36c0aaf355068ad83cb904b8c0b7f5f",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC8o5OUuUconoKe\nASbkganjcX7aByEIai3O5XSC5PxKkEzXGgefaHHtNawJO/nhOmsM1Wqd6sBUy8iT\nbH1LI4hKeIS8k/U0n84VgFUnDdScmsgAbC+06BGEncvqElXI6F9LDqdV21qzu7ZC\n4YpkZuTZsoxImaocUIUE0kfIqq4BZc7kkJqaXqYSOSs2wHLUrQT10jezJmw2EXsx\n+cPD2iwjxasP6IaYCylQr+WU+3e5B2+GKjaXPm7p3pLtSNb+rntvBD212R1VDwuT\nZu+Z2t82Hdsm/r+z1RSKqu1pa2hWYFvSiIl1eV+vqCs4MHdGFinhkNZA9o4NCLBV\nixJxiPDtAgMBAAECggEALu9rR7Ce1Cw2Vx51wRrC/MCPPavS6/9RNP6R8gSMAnhr\nagTDu0W3PPxi+Ow3lPLeUlPigna3kpGerxGqDhFB9reMXUhaFRUi52YmKcCu8yUu\n2K4SY6pvO2Ywp6WWuxWYKjpz57CbnYc5xuPLtYYFcGYUsfar5P4izquMaVEQWO/A\nsABd8gnh0oxwigkk1J9c+qtc6ZKwxgSNOeLld4GFw2z9YBqN70QbEvkrB7JA+QdM\nUFL3edSjEazonGdrySbTh/A7l5E31Oft7qS/VpnFyerhGd3AGFU/FVNpohWiSurD\n9O25xt/YIwpMIOxo0/b4jBv2KMLdOr75MV+2tR8iwQKBgQDj9zSMwO6fm3ZfDrkB\nNw2Qba7Tpn5hW5MshyyPVcpiXMuOyZrjsv19IbVHNZ4Hfl6CRQrGWWDs2rNR6+pW\n+zK82HMzrcwl8A7Dn6GCYQt+EHXiPNXlqJy6v83nFD0TU0BgJn4U21KreLyHxriu\nXnJr062bE9k2MRbp3V/HCiwnrQKBgQDT1krQHdHJyVMNDPbU+EHJVQbuJa4HveE+\n4uDW3srH3dzmlbRgji35EA8WOYJQWc2tiDiwuAFwHB0RoI/EGunCgkVT7qDXcbCm\n3MfHJqrlRGamfAmqT+ZrmDN+izrszVJjaUqiv8/4zbUVfiMF7UZkmeVImIa870t4\nrkdnOdIWQQKBgA30mDb1qKYEsl5nXFQCtsXcsRMr4hi7rmrPa57qtZUH8T4wgVbn\nIjWC1sIhOidjSQ3YhCxYVGKrkMa3FoV0o0qERakoPpMj+wNmxlBg+H8jKtRKvR1u\nEQotq8E1r/d65Tn9oUJNmuX8Yi49sBicl4yaTMptkKKMpsZyUuawbLuRAoGALYOw\nZVDS31krR/WOHyoL8HcdWxOrdaxddgaHKoOJ7DGGIeDudYR26jmCFFNc5Wi2IV/Q\nVl/ipzTTJhNqcEccDJeyz5rI4iFiRCfRoL91Hnd42rJx3S73ogx8m+bMTU68MfHQ\ngHFX/OwtySVl3wMhCcJrGhLzeCqt+4rueoZY1kECgYAuN5gouN8YiqtzvrJ+UtUb\n+BqIu0m+DWMBzrJV4391jpnberxTaMVoQIwCMbHYYJ3u8Ur7smFwyrk5zWvTiszx\nNnPfUD4D6BcNbP8+zwNkzEWnfmtQmh5C5V+DrRjxHSgDu/tirzC7WxPnCJlny3eO\nethubLDwgibzNGemftmqXQ==\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-a4f6g@agrilink-vocpro-b37f9.iam.gserviceaccount.com",
"client_id": "109510416441723731803",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-a4f6g%40agrilink-vocpro-b37f9.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}

View File

@ -0,0 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"agrilink-vocpro-b37f9","appId":"1:445047869982:android:d40dc2fd624f86a315540f","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"agrilink-vocpro-b37f9","configurations":{"android":"1:445047869982:android:d40dc2fd624f86a315540f","ios":"1:445047869982:ios:9350ac31c363c40415540f"}}}}}}

View File

@ -0,0 +1,51 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/constant/app_theme.dart';
import 'package:flutter/material.dart';
class PasswordTextfield extends StatefulWidget {
const PasswordTextfield({
super.key,
required this.controller,
this.hintText = 'Enter Here',
});
final TextEditingController controller;
final String hintText;
@override
State<PasswordTextfield> createState() => _PasswordTextfieldState();
}
class _PasswordTextfieldState extends State<PasswordTextfield> {
bool obscureText = true;
@override
Widget build(BuildContext context) {
return TextField(
controller: widget.controller,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: AppColor.textDisable, width: 1),
borderRadius: BorderRadius.circular(8),
),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: AppColor.primary, width: 1),
borderRadius: BorderRadius.circular(8),
),
hintText: widget.hintText,
hintStyle: AppTheme.hintStyle,
suffixIconColor: AppColor.textDisable,
suffixIcon: IconButton(
onPressed: () {
setState(() {
obscureText = !obscureText;
});
},
icon: obscureText
? const Icon(Icons.visibility_off)
: const Icon(Icons.visibility)),
),
obscureText: obscureText,
onTapOutside: (event) => FocusScope.of(context).unfocus(),
);
}
}

View File

@ -24,8 +24,8 @@ class LatestDataResponse {
class Data {
List<Dht>? dht;
List<Npk1>? npk1;
List<Npk2>? npk2;
List<Npk>? npk1;
List<Npk>? npk2;
Data({this.dht, this.npk1, this.npk2});
@ -37,15 +37,15 @@ class Data {
});
}
if (json['npk1'] != null) {
npk1 = <Npk1>[];
npk1 = <Npk>[];
json['npk1'].forEach((v) {
npk1!.add(Npk1.fromJson(v));
npk1!.add(Npk.fromJson(v));
});
}
if (json['npk2'] != null) {
npk2 = <Npk2>[];
npk2 = <Npk>[];
json['npk2'].forEach((v) {
npk2!.add(Npk2.fromJson(v));
npk2!.add(Npk.fromJson(v));
});
}
}
@ -67,119 +67,74 @@ class Data {
class Dht {
int? hour;
num? vicitemperatureAvg;
num? vicihumidityAvg;
num? viciluminosityAvg;
num? vicitemperature;
num? vicihumidity;
num? viciluminosity;
Dht(
{this.hour,
this.vicitemperatureAvg,
this.vicihumidityAvg,
this.viciluminosityAvg});
this.vicitemperature,
this.vicihumidity,
this.viciluminosity});
Dht.fromJson(Map<String, dynamic> json) {
hour = json['hour'];
vicitemperatureAvg = json['vicitemperature_avg'];
vicihumidityAvg = json['vicihumidity_avg'];
viciluminosityAvg = json['viciluminosity_avg'];
vicitemperature = json['vicitemperature'];
vicihumidity = json['vicihumidity'];
viciluminosity = json['viciluminosity'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['hour'] = hour;
data['vicitemperature_avg'] = vicitemperatureAvg;
data['vicihumidity_avg'] = vicihumidityAvg;
data['viciluminosity_avg'] = viciluminosityAvg;
data['vicitemperature'] = vicitemperature;
data['vicihumidity'] = vicihumidity;
data['viciluminosity'] = viciluminosity;
return data;
}
}
class Npk1 {
class Npk {
int? hour;
num? soiltemperatureAvg;
num? soilhumidityAvg;
num? soilconductivityAvg;
num? soilphAvg;
num? soilnitrogenAvg;
num? soilphosphorusAvg;
num? soilpotassiumAvg;
num? soiltemperature;
num? soilhumidity;
num? soilconductivity;
num? soilph;
num? soilnitrogen;
num? soilphosphorus;
num? soilpotassium;
Npk1(
Npk(
{this.hour,
this.soiltemperatureAvg,
this.soilhumidityAvg,
this.soilconductivityAvg,
this.soilphAvg,
this.soilnitrogenAvg,
this.soilphosphorusAvg,
this.soilpotassiumAvg});
this.soiltemperature,
this.soilhumidity,
this.soilconductivity,
this.soilph,
this.soilnitrogen,
this.soilphosphorus,
this.soilpotassium});
Npk1.fromJson(Map<String, dynamic> json) {
Npk.fromJson(Map<String, dynamic> json) {
hour = json['hour'];
soiltemperatureAvg = json['soiltemperature_avg'];
soilhumidityAvg = json['soilhumidity_avg'];
soilconductivityAvg = json['soilconductivity_avg'];
soilphAvg = json['soilph_avg'];
soilnitrogenAvg = json['soilnitrogen_avg'];
soilphosphorusAvg = json['soilphosphorus_avg'];
soilpotassiumAvg = json['soilpotassium_avg'];
soiltemperature = json['soiltemperature'];
soilhumidity = json['soilhumidity'];
soilconductivity = json['soilconductivity'];
soilph = json['soilph'];
soilnitrogen = json['soilnitrogen'];
soilphosphorus = json['soilphosphorus'];
soilpotassium = json['soilpotassium'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['hour'] = hour;
data['soiltemperature_avg'] = soiltemperatureAvg;
data['soilhumidity_avg'] = soilhumidityAvg;
data['soilconductivity_avg'] = soilconductivityAvg;
data['soilph_avg'] = soilphAvg;
data['soilnitrogen_avg'] = soilnitrogenAvg;
data['soilphosphorus_avg'] = soilphosphorusAvg;
data['soilpotassium_avg'] = soilpotassiumAvg;
return data;
}
}
class Npk2 {
int? hour;
num? soiltemperatureAvg;
num? soilhumidityAvg;
num? soilconductivityAvg;
num? soilphAvg;
num? soilnitrogenAvg;
num? soilphosphorusAvg;
num? soilpotassiumAvg;
Npk2(
{this.hour,
this.soiltemperatureAvg,
this.soilhumidityAvg,
this.soilconductivityAvg,
this.soilphAvg,
this.soilnitrogenAvg,
this.soilphosphorusAvg,
this.soilpotassiumAvg});
Npk2.fromJson(Map<String, dynamic> json) {
hour = json['hour'];
soiltemperatureAvg = json['soiltemperature_avg'];
soilhumidityAvg = json['soilhumidity_avg'];
soilconductivityAvg = json['soilconductivity_avg'];
soilphAvg = json['soilph_avg'];
soilnitrogenAvg = json['soilnitrogen_avg'];
soilphosphorusAvg = json['soilphosphorus_avg'];
soilpotassiumAvg = json['soilpotassium_avg'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['hour'] = hour;
data['soiltemperature_avg'] = soiltemperatureAvg;
data['soilhumidity_avg'] = soilhumidityAvg;
data['soilconductivity_avg'] = soilconductivityAvg;
data['soilph_avg'] = soilphAvg;
data['soilnitrogen_avg'] = soilnitrogenAvg;
data['soilphosphorus_avg'] = soilphosphorusAvg;
data['soilpotassium_avg'] = soilpotassiumAvg;
data['soiltemperature'] = soiltemperature;
data['soilhumidity'] = soilhumidity;
data['soilconductivity'] = soilconductivity;
data['soilph'] = soilph;
data['soilnitrogen'] = soilnitrogen;
data['soilphosphorus'] = soilphosphorus;
data['soilpotassium'] = soilpotassium;
return data;
}
}

View File

@ -25,15 +25,15 @@ class Npk1GraphicResponse {
}
class DataNpk1 {
List<Npk1>? npk1;
List<Npk>? npk1;
DataNpk1({this.npk1});
DataNpk1.fromJson(Map<String, dynamic> json) {
if (json['npk1'] != null) {
npk1 = <Npk1>[];
npk1 = <Npk>[];
json['npk1'].forEach((v) {
npk1!.add(Npk1.fromJson(v));
npk1!.add(Npk.fromJson(v));
});
}
}

View File

@ -25,15 +25,15 @@ class Npk2GraphicResponse {
}
class DataNpk2 {
List<Npk2>? npk2;
List<Npk>? npk2;
DataNpk2({this.npk2});
DataNpk2.fromJson(Map<String, dynamic> json) {
if (json['npk2'] != null) {
npk2 = <Npk2>[];
npk2 = <Npk>[];
json['npk2'].forEach((v) {
npk2!.add(Npk2.fromJson(v));
npk2!.add(Npk.fromJson(v));
});
}
}

View File

@ -18,6 +18,8 @@ class AppService {
final Dio _dioWithoutInterceptor = Dio(
BaseOptions(
baseUrl: AppConstant.baseUrl,
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 5),
),
);
@ -33,6 +35,7 @@ class AppService {
FormData formData = FormData.fromMap({
'remember_me': rememberMe,
});
try {
final response = await _dioWithoutInterceptor.post(
'/auth/login',
@ -59,7 +62,12 @@ class AppService {
throw Exception('Failed to load data');
}
} on DioException catch (e) {
final String errorMessage = e.response?.data['message'];
final String errorMessage;
if (e.response?.data != null) {
errorMessage = e.response?.data['message'] ?? 'Something went wrong';
} else {
errorMessage = 'Something went wrong';
}
throw (errorMessage);
}
}

View File

@ -0,0 +1,20 @@
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
class FirebaseApi {
final _firebaseMessaging = FirebaseMessaging.instance;
Future<void> initNotification() async {
await _firebaseMessaging.requestPermission(
alert: true,
badge: true,
provisional: false,
sound: true,
);
final fCMToken = await _firebaseMessaging.getToken();
if (kDebugMode) {
print('FCM Token: $fCMToken');
}
}
}

View File

@ -1,6 +1,11 @@
import 'dart:convert';
import 'package:agrilink_vocpro/core/state/result_state.dart';
import 'package:agrilink_vocpro/domain/service/app_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:googleapis_auth/auth_io.dart';
import 'package:http/http.dart' as http;
class AuthProvider extends ChangeNotifier {
TextEditingController emailController = TextEditingController();
@ -74,4 +79,31 @@ class AuthProvider extends ChangeNotifier {
}
return true;
}
Future<void> getAccessToken() async {
try {
final serviceAccountJson = await rootBundle.loadString(
'assets/json/agrilink-vocpro-b37f9-firebase-adminsdk-a4f6g-e6565344e3.json',
);
final accountCredentials = ServiceAccountCredentials.fromJson(
json.decode(serviceAccountJson),
);
const scope = ['https://www.googleapis.com/auth/firebase.messaging'];
final client = http.Client();
try {
final accessCredential = await obtainAccessCredentialsViaServiceAccount(
accountCredentials, scope, client);
final accessToken = accessCredential.accessToken.data;
print('Access Token: $accessToken');
} catch (e) {
print('Error: $e');
}
} catch (e) {
print('Error 2: $e');
}
}
}

View File

@ -3,6 +3,7 @@ import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:agrilink_vocpro/core/state/result_state.dart';
import 'package:agrilink_vocpro/core/widgets/app_button.dart';
import 'package:agrilink_vocpro/core/widgets/app_textfield.dart';
import 'package:agrilink_vocpro/core/widgets/password_textfield.dart';
import 'package:agrilink_vocpro/features/auth/provider/auth_provider.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
@ -39,10 +40,9 @@ class LoginScreen extends StatelessWidget {
const SizedBox(height: 24),
Text('Password', style: AppTheme.labelLarge),
const SizedBox(height: 4),
AppTextfield(
PasswordTextfield(
controller: authP.passwordController,
hintText: 'Masukkan password',
obscureText: true,
),
const SizedBox(height: 24),
Row(
@ -76,6 +76,12 @@ class LoginScreen extends StatelessWidget {
},
text: 'Login',
),
SizedBox(height: 24),
AppButton(
onPressed: () {
authP.getAccessToken();
},
text: 'Get Access Token'),
],
);
},

View File

@ -10,8 +10,8 @@ class ConductivityProvider extends ChangeNotifier {
}
ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = [];
List<Npk> dataFetchedNpk1 = [];
List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilConductivityNpk1Data() async {
dataState = ResultState.loading;

View File

@ -140,10 +140,8 @@ class ConductivityScreen extends StatelessWidget {
? provider.dataFetchedNpk1.length
: provider.dataFetchedNpk2.length,
(index) => isNpk1
? provider.dataFetchedNpk1[index].soilconductivityAvg ??
0
: provider.dataFetchedNpk2[index].soilconductivityAvg ??
0,
? provider.dataFetchedNpk1[index].soilconductivity ?? 0
: provider.dataFetchedNpk2[index].soilconductivity ?? 0,
),
maxValue: 1,
);

View File

@ -140,7 +140,7 @@ class HumidityScreen extends StatelessWidget {
data: List.generate(
provider.dataFetched.length,
(index) =>
provider.dataFetched[index].vicihumidityAvg
provider.dataFetched[index].vicihumidity
?.toDouble() ??
0),
);

View File

@ -134,7 +134,7 @@ class LightScreen extends StatelessWidget {
data: List.generate(
provider.dataFetched.length,
(index) =>
provider.dataFetched[index].vicihumidityAvg
provider.dataFetched[index].vicihumidity
?.toDouble() ??
0),
);

View File

@ -10,8 +10,8 @@ class NitrogenProvider extends ChangeNotifier {
}
ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = [];
List<Npk> dataFetchedNpk1 = [];
List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilNitrogenNpk1Data() async {
dataState = ResultState.loading;

View File

@ -140,8 +140,8 @@ class NitrogenScreen extends StatelessWidget {
? provider.dataFetchedNpk1.length
: provider.dataFetchedNpk2.length,
(index) => isNpk1
? provider.dataFetchedNpk1[index].soilnitrogenAvg ?? 0
: provider.dataFetchedNpk2[index].soilnitrogenAvg ?? 0,
? provider.dataFetchedNpk1[index].soilnitrogen ?? 0
: provider.dataFetchedNpk2[index].soilnitrogen ?? 0,
),
maxValue: 1,
);

View File

@ -10,8 +10,8 @@ class PhProvider extends ChangeNotifier {
}
ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = [];
List<Npk> dataFetchedNpk1 = [];
List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilPhNpk1Data() async {
dataState = ResultState.loading;

View File

@ -131,8 +131,8 @@ class PhScreen extends StatelessWidget {
? provider.dataFetchedNpk1.length
: provider.dataFetchedNpk2.length,
(index) => isNpk1
? provider.dataFetchedNpk1[index].soilphAvg ?? 0
: provider.dataFetchedNpk2[index].soilphAvg ?? 0,
? provider.dataFetchedNpk1[index].soilph ?? 0
: provider.dataFetchedNpk2[index].soilph ?? 0,
),
maxValue: 14,
);

View File

@ -10,8 +10,8 @@ class PhosporusProvider extends ChangeNotifier {
}
ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = [];
List<Npk> dataFetchedNpk1 = [];
List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilPhosporNpk1Data() async {
dataState = ResultState.loading;

View File

@ -140,9 +140,8 @@ class PhosphorusScreen extends StatelessWidget {
? provider.dataFetchedNpk1.length
: provider.dataFetchedNpk2.length,
(index) => isNpk1
? provider.dataFetchedNpk1[index].soilphosphorusAvg ?? 0
: provider.dataFetchedNpk2[index].soilphosphorusAvg ??
0,
? provider.dataFetchedNpk1[index].soilphosphorus ?? 0
: provider.dataFetchedNpk2[index].soilphosphorus ?? 0,
),
maxValue: 10,
);

View File

@ -10,8 +10,8 @@ class PotassiumProvider extends ChangeNotifier {
}
ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = [];
List<Npk> dataFetchedNpk1 = [];
List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilPotassiumNpk1Data() async {
dataState = ResultState.loading;

View File

@ -140,8 +140,8 @@ class PotassiumScreen extends StatelessWidget {
? provider.dataFetchedNpk1.length
: provider.dataFetchedNpk2.length,
(index) => isNpk1
? provider.dataFetchedNpk1[index].soilpotassiumAvg ?? 0
: provider.dataFetchedNpk2[index].soilpotassiumAvg ?? 0,
? provider.dataFetchedNpk1[index].soilpotassium ?? 0
: provider.dataFetchedNpk2[index].soilpotassium ?? 0,
),
maxValue: 1,
);

View File

@ -10,8 +10,8 @@ class SoilMoistureProvider extends ChangeNotifier {
}
ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = [];
List<Npk> dataFetchedNpk1 = [];
List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilMosNpk1Data() async {
dataState = ResultState.loading;

View File

@ -170,8 +170,8 @@ class SoilMoistureScreen extends StatelessWidget {
? provider.dataFetchedNpk1.length
: provider.dataFetchedNpk2.length,
(index) => isNpk1
? provider.dataFetchedNpk1[index].soilhumidityAvg ?? 0
: provider.dataFetchedNpk2[index].soilhumidityAvg ?? 0,
? provider.dataFetchedNpk1[index].soilhumidity ?? 0
: provider.dataFetchedNpk2[index].soilhumidity ?? 0,
),
maxValue: 1,
);

View File

@ -10,8 +10,8 @@ class SoilTempProvider extends ChangeNotifier {
}
ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = [];
List<Npk> dataFetchedNpk1 = [];
List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilTempNpk1Data() async {
dataState = ResultState.loading;

View File

@ -220,10 +220,8 @@ class SoilTemperatureScreen extends StatelessWidget {
? provider.dataFetchedNpk1.length
: provider.dataFetchedNpk2.length,
(index) => isNpk1
? provider.dataFetchedNpk1[index].soiltemperatureAvg ??
0
: provider.dataFetchedNpk2[index].soiltemperatureAvg ??
0,
? provider.dataFetchedNpk1[index].soiltemperature ?? 0
: provider.dataFetchedNpk2[index].soiltemperature ?? 0,
),
maxValue: 70,
);

View File

@ -223,8 +223,7 @@ class TemperatureScreen extends StatelessWidget {
data: List.generate(
provider.dataFetched.length,
(index) =>
provider
.dataFetched[index].vicitemperatureAvg
provider.dataFetched[index].vicitemperature
?.toDouble() ??
0),
);

View File

@ -72,25 +72,25 @@ class HomeProvider extends ChangeNotifier {
notifyListeners();
} else {
final data = result.data!;
_dhtHumidity = data.dht?[0].vicihumidityAvg ?? 0;
_dhtTemperature = data.dht?[0].vicitemperatureAvg ?? 0;
_dhtLuminosity = data.dht?[0].viciluminosityAvg ?? 0;
_dhtHumidity = data.dht?[0].vicihumidity ?? 0;
_dhtTemperature = data.dht?[0].vicitemperature ?? 0;
_dhtLuminosity = data.dht?[0].viciluminosity ?? 0;
_npk1SoilMoisture = data.npk1?[0].soilhumidityAvg ?? 0;
_npk1Temperature = data.npk1?[0].soiltemperatureAvg ?? 0;
_npk1SoilPh = data.npk1?[0].soilphAvg ?? 0;
_npk1SoilEc = data.npk1?[0].soilconductivityAvg ?? 0;
_npk1SoilNitrogen = data.npk1?[0].soilnitrogenAvg ?? 0;
_npk1SoilPhosphorus = data.npk1?[0].soilphosphorusAvg ?? 0;
_npk1SoilPotassium = data.npk1?[0].soilpotassiumAvg ?? 0;
_npk1SoilMoisture = data.npk1?[0].soilhumidity ?? 0;
_npk1Temperature = data.npk1?[0].soiltemperature ?? 0;
_npk1SoilPh = data.npk1?[0].soilph ?? 0;
_npk1SoilEc = data.npk1?[0].soilconductivity ?? 0;
_npk1SoilNitrogen = data.npk1?[0].soilnitrogen ?? 0;
_npk1SoilPhosphorus = data.npk1?[0].soilphosphorus ?? 0;
_npk1SoilPotassium = data.npk1?[0].soilpotassium ?? 0;
_npk2SoilMoisture = data.npk2?[0].soilhumidityAvg ?? 0;
_npk2Temperature = data.npk2?[0].soiltemperatureAvg ?? 0;
_npk2SoilPh = data.npk2?[0].soilphAvg ?? 0;
_npk2SoilEc = data.npk2?[0].soilconductivityAvg ?? 0;
_npk2SoilNitrogen = data.npk2?[0].soilnitrogenAvg ?? 0;
_npk2SoilPhosphorus = data.npk2?[0].soilphosphorusAvg ?? 0;
_npk2SoilPotassium = data.npk2?[0].soilpotassiumAvg ?? 0;
_npk2SoilMoisture = data.npk2?[0].soilhumidity ?? 0;
_npk2Temperature = data.npk2?[0].soiltemperature ?? 0;
_npk2SoilPh = data.npk2?[0].soilph ?? 0;
_npk2SoilEc = data.npk2?[0].soilconductivity ?? 0;
_npk2SoilNitrogen = data.npk2?[0].soilnitrogen ?? 0;
_npk2SoilPhosphorus = data.npk2?[0].soilphosphorus ?? 0;
_npk2SoilPotassium = data.npk2?[0].soilpotassium ?? 0;
dataState = ResultState.hasData;
notifyListeners();
}

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
@ -20,6 +21,7 @@ class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
FirebaseMessaging.instance.subscribeToTopic('smartfarm');
_initialize();
}

View File

@ -0,0 +1,68 @@
// File generated by FlutterFire CLI.
// ignore_for_file: type=lint
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyCB8i2dE3Oc0kTNtVPw_qSz-T8gPYNjxFk',
appId: '1:445047869982:android:d40dc2fd624f86a315540f',
messagingSenderId: '445047869982',
projectId: 'agrilink-vocpro-b37f9',
storageBucket: 'agrilink-vocpro-b37f9.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyDZO8tEZFcQrJMwJG_viJTbITWNVqxJo8E',
appId: '1:445047869982:ios:9350ac31c363c40415540f',
messagingSenderId: '445047869982',
projectId: 'agrilink-vocpro-b37f9',
storageBucket: 'agrilink-vocpro-b37f9.appspot.com',
iosBundleId: 'com.pis.agrilinkVocpro',
);
}

View File

@ -1,16 +1,21 @@
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:agrilink_vocpro/domain/service/firebase_api.dart';
import 'package:agrilink_vocpro/features/auth/provider/auth_provider.dart';
import 'package:agrilink_vocpro/features/control/provider/control_provider.dart';
import 'package:agrilink_vocpro/features/dashboard/provider/dashboard_provider.dart';
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
import 'package:agrilink_vocpro/features/setting/provider/setting_provider.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
void main() {
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
final firebaseApi = FirebaseApi();
await firebaseApi.initNotification();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp, // Locks the app in portrait mode
]).then((_) {

View File

@ -5,10 +5,14 @@
import FlutterMacOS
import Foundation
import firebase_core
import firebase_messaging
import path_provider_foundation
import shared_preferences_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
}

View File

@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2"
url: "https://pub.dev"
source: hosted
version: "1.3.44"
animated_segmented_tab_control:
dependency: "direct main"
description:
@ -9,6 +17,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
args:
dependency: transitive
description:
name: args
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
url: "https://pub.dev"
source: hosted
version: "2.6.0"
async:
dependency: transitive
description:
@ -145,6 +161,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.1"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96"
url: "https://pub.dev"
source: hosted
version: "3.6.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810
url: "https://pub.dev"
source: hosted
version: "5.3.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5
url: "https://pub.dev"
source: hosted
version: "2.18.1"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
sha256: eb6e28a3a35deda61fe8634967c84215efc19133ba58d8e0fc6c9a2af2cba05e
url: "https://pub.dev"
source: hosted
version: "15.1.3"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
sha256: b316c4ee10d93d32c033644207afc282d9b2b4372f3cf9c6022f3558b3873d2d
url: "https://pub.dev"
source: hosted
version: "4.5.46"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
sha256: d7f0147a1a9fe4313168e20154a01fd5cf332898de1527d3930ff77b8c7f5387
url: "https://pub.dev"
source: hosted
version: "3.9.2"
fl_chart:
dependency: "direct main"
description:
@ -208,6 +272,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.2.1"
google_identity_services_web:
dependency: transitive
description:
name: google_identity_services_web
sha256: "5be191523702ba8d7a01ca97c17fca096822ccf246b0a9f11923a6ded06199b6"
url: "https://pub.dev"
source: hosted
version: "0.3.1+4"
googleapis_auth:
dependency: "direct main"
description:
name: googleapis_auth
sha256: befd71383a955535060acde8792e7efc11d2fccd03dd1d3ec434e85b68775938
url: "https://pub.dev"
source: hosted
version: "1.6.0"
html:
dependency: transitive
description:
@ -217,7 +297,7 @@ packages:
source: hosted
version: "0.15.4"
http:
dependency: transitive
dependency: "direct main"
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010

View File

@ -48,6 +48,10 @@ dependencies:
mqtt_client: ^10.5.1
shimmer: ^3.0.0
jwt_decoder: ^2.0.1
firebase_core: ^3.6.0
firebase_messaging: ^15.1.3
googleapis_auth: ^1.6.0
http: ^1.2.2
dev_dependencies:
flutter_test:
@ -74,6 +78,7 @@ flutter:
assets:
- assets/images/
- assets/icons/
- assets/json/
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see

View File

@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h"
#include <firebase_core/firebase_core_plugin_c_api.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
}

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
firebase_core
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST