Primer MVP

This commit is contained in:
hack_23030943_f11325
2026-05-22 19:44:31 -06:00
parent acccfbc98c
commit 369060a997
9 changed files with 141 additions and 50 deletions

2
.gitignore vendored
View File

@@ -118,3 +118,5 @@ app.*.symbols
!**/ios/**/default.perspectivev3 !**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!/dev/ci/**/Gemfile.lock !/dev/ci/**/Gemfile.lock
firebase-credentials.json

View File

@@ -20,6 +20,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 "9.0.1" apply false id("com.android.application") version "9.0.1" 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 "2.3.20" apply false id("org.jetbrains.kotlin.android") version "2.3.20" apply false
} }

Binary file not shown.

View File

@@ -0,0 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"hackon-58b23","appId":"1:338042609701:android:0f0f92d7f895794f371fcc","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"hackon-58b23","configurations":{"android":"1:338042609701:android:0f0f92d7f895794f371fcc","ios":"1:338042609701:ios:d1ac418d368d1df5371fcc","macos":"1:338042609701:ios:d1ac418d368d1df5371fcc","web":"1:338042609701:web:5f0a245f364e7604371fcc","windows":"1:338042609701:web:b01c28c419fddd25371fcc"}}}}}}

View File

@@ -0,0 +1,88 @@
// 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) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
case TargetPlatform.windows:
return windows;
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 web = FirebaseOptions(
apiKey: 'AIzaSyDfpYR_--oRlGdTjLnAZY6z3RLh3LLz5gk',
appId: '1:338042609701:web:5f0a245f364e7604371fcc',
messagingSenderId: '338042609701',
projectId: 'hackon-58b23',
authDomain: 'hackon-58b23.firebaseapp.com',
storageBucket: 'hackon-58b23.firebasestorage.app',
measurementId: 'G-TBT47P2HX5',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyBuT70SbADLeg92ll8keCySI8I4eYyqyLw',
appId: '1:338042609701:android:0f0f92d7f895794f371fcc',
messagingSenderId: '338042609701',
projectId: 'hackon-58b23',
storageBucket: 'hackon-58b23.firebasestorage.app',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyAB7czRjHfrkHEjiDOvPLiUz9zS1UGiZbw',
appId: '1:338042609701:ios:d1ac418d368d1df5371fcc',
messagingSenderId: '338042609701',
projectId: 'hackon-58b23',
storageBucket: 'hackon-58b23.firebasestorage.app',
iosBundleId: 'com.example.aplicacionHack',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyAB7czRjHfrkHEjiDOvPLiUz9zS1UGiZbw',
appId: '1:338042609701:ios:d1ac418d368d1df5371fcc',
messagingSenderId: '338042609701',
projectId: 'hackon-58b23',
storageBucket: 'hackon-58b23.firebasestorage.app',
iosBundleId: 'com.example.aplicacionHack',
);
static const FirebaseOptions windows = FirebaseOptions(
apiKey: 'AIzaSyDfpYR_--oRlGdTjLnAZY6z3RLh3LLz5gk',
appId: '1:338042609701:web:b01c28c419fddd25371fcc',
messagingSenderId: '338042609701',
projectId: 'hackon-58b23',
authDomain: 'hackon-58b23.firebaseapp.com',
storageBucket: 'hackon-58b23.firebasestorage.app',
measurementId: 'G-DYGG6KBJ6C',
);
}

View File

@@ -17,7 +17,7 @@ import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'screens/login_screen.dart'; import 'screens/login_screen.dart';
import 'screens/home_screen.dart'; import 'screens/home_screen.dart';
import 'firebase_options.dart'; // Opcional si usas FlutterFire CLI para generar opciones
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// HANDLER DE MENSAJES EN BACKGROUND // HANDLER DE MENSAJES EN BACKGROUND
// //
@@ -29,7 +29,7 @@ import 'screens/home_screen.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// IMPORTANTE: Si el handler hace operaciones async pesadas, // IMPORTANTE: Si el handler hace operaciones async pesadas,
// también hay que inicializar Firebase aquí. // también hay que inicializar Firebase aquí.
await Firebase.initializeApp(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
debugPrint('📬 [Background] Mensaje recibido: ${message.messageId}'); debugPrint('📬 [Background] Mensaje recibido: ${message.messageId}');
// TODO: Aquí puedes guardar el mensaje en local storage para mostrarlo // TODO: Aquí puedes guardar el mensaje en local storage para mostrarlo
// después cuando el usuario abra la app. // después cuando el usuario abra la app.

View File

@@ -24,7 +24,7 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
// Descomenta cuando Firebase esté configurado: // Descomenta cuando Firebase esté configurado:
// import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import '../services/api_service.dart'; import '../services/api_service.dart';
class HomeScreen extends StatefulWidget { class HomeScreen extends StatefulWidget {
@@ -89,7 +89,7 @@ class _HomeScreenState extends State<HomeScreen>
_usuarioId = args; _usuarioId = args;
_cargarETA(); _cargarETA();
_iniciarAutoRefresh(); _iniciarAutoRefresh();
// _registrarFCMToken(); // Activar cuando Firebase esté listo _registrarFCMToken(); // Activar cuando Firebase esté listo
} else { } else {
// Fallback: leer de shared_preferences si no viene por argumento // Fallback: leer de shared_preferences si no viene por argumento
_cargarUsuarioDeStorage(); _cargarUsuarioDeStorage();
@@ -179,43 +179,41 @@ class _HomeScreenState extends State<HomeScreen>
// manda al backend para poder recibir notificaciones push. // manda al backend para poder recibir notificaciones push.
// DESCOMENTA cuando tengas Firebase configurado. // DESCOMENTA cuando tengas Firebase configurado.
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// Future<void> _registrarFCMToken() async { Future<void> _registrarFCMToken() async {
// try { try {
// final messaging = FirebaseMessaging.instance; final messaging = FirebaseMessaging.instance;
//
// // Pedir permisos de notificación al usuario (iOS requiere esto) // Pedir permisos de notificación al usuario (iOS requiere esto)
// final settings = await messaging.requestPermission( final settings = await messaging.requestPermission(
// alert: true, alert: true,
// sound: true, sound: true,
// badge: true, badge: true,
// ); );
// if (settings.authorizationStatus == AuthorizationStatus.authorized) {
// if (settings.authorizationStatus == AuthorizationStatus.authorized) { final token = await messaging.getToken();
// final token = await messaging.getToken(); if (token != null && _usuarioId != null) {
// if (token != null && _usuarioId != null) { await _apiService.registrarFcmToken(_usuarioId!, token);
// await _apiService.registrarFcmToken(_usuarioId!, token); debugPrint('✅ FCM Token registrado: ${token.substring(0, 20)}...');
// debugPrint('✅ FCM Token registrado: ${token.substring(0, 20)}...'); }
// } }
// } // Escuchar notificaciones cuando la app está en FOREGROUND
// FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// // Escuchar notificaciones cuando la app está en FOREGROUND if (message.notification != null && mounted) {
// FirebaseMessaging.onMessage.listen((RemoteMessage message) { ScaffoldMessenger.of(context).showSnackBar(
// if (message.notification != null && mounted) { SnackBar(
// ScaffoldMessenger.of(context).showSnackBar( content: Text('🚛 ${message.notification!.body}'),
// SnackBar( backgroundColor: Colors.green.shade700,
// content: Text('🚛 ${message.notification!.body}'), duration: const Duration(seconds: 5),
// backgroundColor: Colors.green.shade700, ),
// duration: const Duration(seconds: 5), );
// ), // Refrescar ETA al recibir notificación
// ); _cargarETA();
// // Refrescar ETA al recibir notificación }
// _cargarETA(); });
// } } catch (e) {
// }); debugPrint('Error registrando FCM token: $e');
// } catch (e) { }
// debugPrint('Error registrando FCM token: $e'); }
// }
// }
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// CERRAR SESIÓN // CERRAR SESIÓN

Binary file not shown.

View File

@@ -140,16 +140,15 @@ TIPOS_EVENTO_VALIDOS = ["en_camino", "llegando", "completado", "retrasado"]
import firebase_admin import firebase_admin
from firebase_admin import credentials, messaging from firebase_admin import credentials, messaging
# --- DESCOMENTA ESTO CUANDO TENGAS EL ARCHIVO DE CREDENCIALES --- try:
# try: cred = credentials.Certificate("firebase-credentials.json")
# cred = credentials.Certificate("firebase-credentials.json") firebase_admin.initialize_app(cred)
# firebase_admin.initialize_app(cred) logger.info("✅ Firebase Admin SDK inicializado correctamente")
# logger.info("✅ Firebase Admin SDK inicializado correctamente") except Exception as e:
# except Exception as e: logger.error(f"❌ Error inicializando Firebase: {e}")
# logger.error(f"❌ Error inicializando Firebase: {e}")
# ---------------------------------------------------------------
FIREBASE_ACTIVO = False # Cambia a True al desbloquear Firebase
FIREBASE_ACTIVO = True # Cambia a True al desbloquear Firebase
# =============================================================== # ===============================================================