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 { plugins {
id "com.android.application" id "com.android.application"
// START: FlutterFire Configuration
id 'com.google.gms.google-services'
// END: FlutterFire Configuration
id "kotlin-android" id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin" id "dev.flutter.flutter-gradle-plugin"
@ -24,7 +27,7 @@ android {
applicationId = "com.pis.agrilink_vocpro" applicationId = "com.pis.agrilink_vocpro"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion minSdk = 21
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode versionCode = flutter.versionCode
versionName = flutter.versionName 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 { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false 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 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 { class Data {
List<Dht>? dht; List<Dht>? dht;
List<Npk1>? npk1; List<Npk>? npk1;
List<Npk2>? npk2; List<Npk>? npk2;
Data({this.dht, this.npk1, this.npk2}); Data({this.dht, this.npk1, this.npk2});
@ -37,15 +37,15 @@ class Data {
}); });
} }
if (json['npk1'] != null) { if (json['npk1'] != null) {
npk1 = <Npk1>[]; npk1 = <Npk>[];
json['npk1'].forEach((v) { json['npk1'].forEach((v) {
npk1!.add(Npk1.fromJson(v)); npk1!.add(Npk.fromJson(v));
}); });
} }
if (json['npk2'] != null) { if (json['npk2'] != null) {
npk2 = <Npk2>[]; npk2 = <Npk>[];
json['npk2'].forEach((v) { json['npk2'].forEach((v) {
npk2!.add(Npk2.fromJson(v)); npk2!.add(Npk.fromJson(v));
}); });
} }
} }
@ -67,119 +67,74 @@ class Data {
class Dht { class Dht {
int? hour; int? hour;
num? vicitemperatureAvg; num? vicitemperature;
num? vicihumidityAvg; num? vicihumidity;
num? viciluminosityAvg; num? viciluminosity;
Dht( Dht(
{this.hour, {this.hour,
this.vicitemperatureAvg, this.vicitemperature,
this.vicihumidityAvg, this.vicihumidity,
this.viciluminosityAvg}); this.viciluminosity});
Dht.fromJson(Map<String, dynamic> json) { Dht.fromJson(Map<String, dynamic> json) {
hour = json['hour']; hour = json['hour'];
vicitemperatureAvg = json['vicitemperature_avg']; vicitemperature = json['vicitemperature'];
vicihumidityAvg = json['vicihumidity_avg']; vicihumidity = json['vicihumidity'];
viciluminosityAvg = json['viciluminosity_avg']; viciluminosity = json['viciluminosity'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['hour'] = hour; data['hour'] = hour;
data['vicitemperature_avg'] = vicitemperatureAvg; data['vicitemperature'] = vicitemperature;
data['vicihumidity_avg'] = vicihumidityAvg; data['vicihumidity'] = vicihumidity;
data['viciluminosity_avg'] = viciluminosityAvg; data['viciluminosity'] = viciluminosity;
return data; return data;
} }
} }
class Npk1 { class Npk {
int? hour; int? hour;
num? soiltemperatureAvg; num? soiltemperature;
num? soilhumidityAvg; num? soilhumidity;
num? soilconductivityAvg; num? soilconductivity;
num? soilphAvg; num? soilph;
num? soilnitrogenAvg; num? soilnitrogen;
num? soilphosphorusAvg; num? soilphosphorus;
num? soilpotassiumAvg; num? soilpotassium;
Npk1( Npk(
{this.hour, {this.hour,
this.soiltemperatureAvg, this.soiltemperature,
this.soilhumidityAvg, this.soilhumidity,
this.soilconductivityAvg, this.soilconductivity,
this.soilphAvg, this.soilph,
this.soilnitrogenAvg, this.soilnitrogen,
this.soilphosphorusAvg, this.soilphosphorus,
this.soilpotassiumAvg}); this.soilpotassium});
Npk1.fromJson(Map<String, dynamic> json) { Npk.fromJson(Map<String, dynamic> json) {
hour = json['hour']; hour = json['hour'];
soiltemperatureAvg = json['soiltemperature_avg']; soiltemperature = json['soiltemperature'];
soilhumidityAvg = json['soilhumidity_avg']; soilhumidity = json['soilhumidity'];
soilconductivityAvg = json['soilconductivity_avg']; soilconductivity = json['soilconductivity'];
soilphAvg = json['soilph_avg']; soilph = json['soilph'];
soilnitrogenAvg = json['soilnitrogen_avg']; soilnitrogen = json['soilnitrogen'];
soilphosphorusAvg = json['soilphosphorus_avg']; soilphosphorus = json['soilphosphorus'];
soilpotassiumAvg = json['soilpotassium_avg']; soilpotassium = json['soilpotassium'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['hour'] = hour; data['hour'] = hour;
data['soiltemperature_avg'] = soiltemperatureAvg; data['soiltemperature'] = soiltemperature;
data['soilhumidity_avg'] = soilhumidityAvg; data['soilhumidity'] = soilhumidity;
data['soilconductivity_avg'] = soilconductivityAvg; data['soilconductivity'] = soilconductivity;
data['soilph_avg'] = soilphAvg; data['soilph'] = soilph;
data['soilnitrogen_avg'] = soilnitrogenAvg; data['soilnitrogen'] = soilnitrogen;
data['soilphosphorus_avg'] = soilphosphorusAvg; data['soilphosphorus'] = soilphosphorus;
data['soilpotassium_avg'] = soilpotassiumAvg; data['soilpotassium'] = soilpotassium;
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;
return data; return data;
} }
} }

View File

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

View File

@ -25,15 +25,15 @@ class Npk2GraphicResponse {
} }
class DataNpk2 { class DataNpk2 {
List<Npk2>? npk2; List<Npk>? npk2;
DataNpk2({this.npk2}); DataNpk2({this.npk2});
DataNpk2.fromJson(Map<String, dynamic> json) { DataNpk2.fromJson(Map<String, dynamic> json) {
if (json['npk2'] != null) { if (json['npk2'] != null) {
npk2 = <Npk2>[]; npk2 = <Npk>[];
json['npk2'].forEach((v) { 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( final Dio _dioWithoutInterceptor = Dio(
BaseOptions( BaseOptions(
baseUrl: AppConstant.baseUrl, baseUrl: AppConstant.baseUrl,
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 5),
), ),
); );
@ -33,6 +35,7 @@ class AppService {
FormData formData = FormData.fromMap({ FormData formData = FormData.fromMap({
'remember_me': rememberMe, 'remember_me': rememberMe,
}); });
try { try {
final response = await _dioWithoutInterceptor.post( final response = await _dioWithoutInterceptor.post(
'/auth/login', '/auth/login',
@ -59,7 +62,12 @@ class AppService {
throw Exception('Failed to load data'); throw Exception('Failed to load data');
} }
} on DioException catch (e) { } 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); 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/core/state/result_state.dart';
import 'package:agrilink_vocpro/domain/service/app_service.dart'; import 'package:agrilink_vocpro/domain/service/app_service.dart';
import 'package:flutter/material.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 { class AuthProvider extends ChangeNotifier {
TextEditingController emailController = TextEditingController(); TextEditingController emailController = TextEditingController();
@ -74,4 +79,31 @@ class AuthProvider extends ChangeNotifier {
} }
return true; 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/state/result_state.dart';
import 'package:agrilink_vocpro/core/widgets/app_button.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/app_textfield.dart';
import 'package:agrilink_vocpro/core/widgets/password_textfield.dart';
import 'package:agrilink_vocpro/features/auth/provider/auth_provider.dart'; import 'package:agrilink_vocpro/features/auth/provider/auth_provider.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -39,10 +40,9 @@ class LoginScreen extends StatelessWidget {
const SizedBox(height: 24), const SizedBox(height: 24),
Text('Password', style: AppTheme.labelLarge), Text('Password', style: AppTheme.labelLarge),
const SizedBox(height: 4), const SizedBox(height: 4),
AppTextfield( PasswordTextfield(
controller: authP.passwordController, controller: authP.passwordController,
hintText: 'Masukkan password', hintText: 'Masukkan password',
obscureText: true,
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
Row( Row(
@ -76,6 +76,12 @@ class LoginScreen extends StatelessWidget {
}, },
text: 'Login', 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; ResultState dataState = ResultState.initial;
List<Npk1> dataFetchedNpk1 = []; List<Npk> dataFetchedNpk1 = [];
List<Npk2> dataFetchedNpk2 = []; List<Npk> dataFetchedNpk2 = [];
Future<void> getSoilConductivityNpk1Data() async { Future<void> getSoilConductivityNpk1Data() async {
dataState = ResultState.loading; dataState = ResultState.loading;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:agrilink_vocpro/core/route/app_route.dart'; import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -20,6 +21,7 @@ class _SplashScreenState extends State<SplashScreen> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
FirebaseMessaging.instance.subscribeToTopic('smartfarm');
_initialize(); _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/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/auth/provider/auth_provider.dart';
import 'package:agrilink_vocpro/features/control/provider/control_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/dashboard/provider/dashboard_provider.dart';
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart'; import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
import 'package:agrilink_vocpro/features/setting/provider/setting_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/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
void main() { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
final firebaseApi = FirebaseApi();
await firebaseApi.initNotification();
SystemChrome.setPreferredOrientations([ SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp, // Locks the app in portrait mode DeviceOrientation.portraitUp, // Locks the app in portrait mode
]).then((_) { ]).then((_) {

View File

@ -5,10 +5,14 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import firebase_core
import firebase_messaging
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 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")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
} }

View File

@ -1,6 +1,14 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2"
url: "https://pub.dev"
source: hosted
version: "1.3.44"
animated_segmented_tab_control: animated_segmented_tab_control:
dependency: "direct main" dependency: "direct main"
description: description:
@ -9,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
args:
dependency: transitive
description:
name: args
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
url: "https://pub.dev"
source: hosted
version: "2.6.0"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -145,6 +161,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.1" 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: fl_chart:
dependency: "direct main" dependency: "direct main"
description: description:
@ -208,6 +272,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.1" 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: html:
dependency: transitive dependency: transitive
description: description:
@ -217,7 +297,7 @@ packages:
source: hosted source: hosted
version: "0.15.4" version: "0.15.4"
http: http:
dependency: transitive dependency: "direct main"
description: description:
name: http name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010

View File

@ -48,6 +48,10 @@ dependencies:
mqtt_client: ^10.5.1 mqtt_client: ^10.5.1
shimmer: ^3.0.0 shimmer: ^3.0.0
jwt_decoder: ^2.0.1 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: dev_dependencies:
flutter_test: flutter_test:
@ -74,6 +78,7 @@ flutter:
assets: assets:
- assets/images/ - assets/images/
- assets/icons/ - assets/icons/
- assets/json/
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see # 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 "generated_plugin_registrant.h"
#include <firebase_core/firebase_core_plugin_c_api.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
} }

View File

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