How to implement authentication in flutter using riverpod - flutter

I am trying to do a login using riverpod, the login must call an api but at the moment I am using a fake api I want that while the api is called I can show a loader to the user and if everything is correct navigate to home.
I have the following:
authentication_service.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:watch_movie_app/src/data/data_source/local/fake_data.dart';
import 'package:watch_movie_app/src/data/models/models.dart';
import 'package:watch_movie_app/src/domain/models/models.dart';
class AuthenticationService {
Future<Auth> login(User user) async {
await Future.delayed(const Duration(seconds: 2));
User isName = fakeUsers.firstWhere(
(element) => element.name == user.name,
orElse: () => emptyUser(),
);
User isPassword = fakeUsers.firstWhere(
(element) => element.password == user.password,
orElse: () => emptyUser(),
);
if (isName.name != '' && isPassword.password != '') {
return Auth(
message: 'Succes welcome user',
status: true,
aditionalData: getRandomString(15));
}
return Auth(message: 'Credenciales incorrectas', status: false);
}
}
auth_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:watch_movie_app/src/data/enums/enum_login_status.dart';
import 'package:watch_movie_app/src/domain/constants/constants.dart';
import 'package:watch_movie_app/src/domain/providers/app_providers.dart';
final userAuthProvider = StateProvider<Map<String, dynamic>>((_) => {
'signedIn': false,
'loaded': false,
'status': LoginStatus.initialize,
});
final saveUserTokenProvider = StateProvider.family<bool, String>((ref, token) {
final localStore = ref.read(localStoreProvider);
localStore.write(tokenKey, token);
return true;
});
final userTokenProvider = StateProvider<String>((ref) {
final localStore = ref.read(localStoreProvider);
return localStore.read(tokenKey);
});
login_controller.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:watch_movie_app/src/data/enums/enum_login_status.dart';
import 'package:watch_movie_app/src/data/models/models.dart';
import 'package:watch_movie_app/src/domain/models/models.dart';
import 'package:watch_movie_app/src/domain/providers/auth_provider.dart';
import 'package:watch_movie_app/src/domain/services/authentication_service.dart';
final authProvider = StateNotifierProvider((ref) => AuthNotifier(ref));
class AuthNotifier extends StateNotifier<Auth> {
final WidgetRef ref;
dynamic _authRepository;
AuthNotifier(this.ref) : super(Auth()) {
_authRepository = ref.read(authRepository);
}
Future<void> login(User user) async {
Map<String, dynamic> userAuthStatus = ref.read(userAuthProvider.state).state;
userAuthStatus = {...userAuthStatus, 'loaded': true};
final Auth loginResult = await _authRepository.login(user);
state = loginResult;
if (loginResult.status) {
userAuthStatus = {'loaded': false, 'signedIn': true, 'status': LoginStatus.success};
} else {
userAuthStatus = {...userAuthStatus, 'loaded': false, 'status': LoginStatus.failed};
}
}
void clearUser() {
state = Auth();
}
}
auth.dart
class Auth {
final String message, aditionalData;
bool status;
Auth({this.message = '', this.status = false, this.aditionalData = ''});
}
versions packages:
flutter_riverpod: ^2.0.0-dev.0
Flutter 2.10.2
Dart 2.15.1 DevTools 2.9.2

Related

Flutter GoRouter with Firebase Auth

This bounty has ended. Answers to this question are eligible for a +100 reputation bounty. Bounty grace period ends in 21 hours.
Chris wants to draw more attention to this question.
I am using the go_router and Firebase Auth for my web application but can not properly set it up. I tried this:
class AuthService {
static final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
static User? get currentUser => FirebaseAuth.instance.currentUser;
static bool isLoggedIn() {
return _firebaseAuth.currentUser != null;
}
...
With my router:
redirect: (context, state) {
final String destination = state.location;
final bool isOnStartView = destination == '/start';
final bool isOnEmailFlow = state.subloc.contains('/email');
if (!isOnStartView && !isOnEmailFlow && !AuthService.isLoggedIn()) {
return '/start';
}
return null;
},
However this is not working properly as isLoggedIn is always return false even if there a is a user logged in. I searched for this topic and found that I probably use some sort of Stream or Notifier with onAuthStateChange but I didn't find anything on how to implement a proper FirebaseAuthentication Flow in combination with GoRouter.
How would I do that?
Let me know if you need any more info.
You can use riverpod or provider to listen changes
here is code sample
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:testproject/Home%20Screen/home_screen.dart';
import 'package:testproject/Model/user_model.dart';
import 'package:testproject/Providers/UserProvider/user_data_provider.dart';
import 'package:testproject/Screens/login_screen.dart';
import 'package:testproject/Screens/sign_up.dart';
import 'package:testproject/Service/auth_service.dart';
import '../Providers/Satates/user_states.dart';
import '../Providers/UserProvider/user_state_provider.dart';
class MyRoutes extends ChangeNotifier {
final Ref ref;
MyRoutes(this.ref) {
ref.listen<LoginState>(
userStateprovider, (previous, next) => notifyListeners());
}
List<GoRoute> get _routes => [
GoRoute(
name: "Login",
path: "/login",
builder: (context, state) => SigninPage(),
),
GoRoute(
name: "Home",
path: "/home",
builder: (context, state) => const HomeScreen(),
),
GoRoute(
name: "Signup",
path: "/signup",
builder: (context, state) => const SignUpScreen(),
),
];
String? _redirectLogic(GoRouterState state) {
final loginState = ref.read(userStateprovider);
final user = ref.read(userProvider.state);
if (loginState is LoginStateInitial && auth.currentUser != null) {
log("message");
Future.delayed(const Duration(seconds: 0), () {
user.state = UserModel(
email: auth.currentUser!.email!, userid: auth.currentUser!.uid);
ref.read(userStateprovider.notifier).newstate = LoginStateSuccess(
UserModel(
email: auth.currentUser!.email!,
userid: auth.currentUser!.uid));
});
}
log(state.location);
log(auth.currentUser.toString());
final areWeLoggingIn = state.location == '/home';
log(areWeLoggingIn.toString());
if (areWeLoggingIn) {
return loginState is LoginStateSuccess ? null : "/login";
}
return null;
}
}
final routeProvider = Provider<GoRouter>((ref) {
final routeRef = MyRoutes(ref);
return GoRouter(
urlPathStrategy: UrlPathStrategy.path,
initialLocation: "/login",
refreshListenable: routeRef,
redirect: routeRef._redirectLogic,
routes: routeRef._routes);
});
You can do this
class AuthService {
static final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
static User? get currentUser => FirebaseAuth.instance.currentUser;
static bool? _isLoggedIn = null;
static bool isLoggedIn() {
if(_isLoggedIn == null) {
FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
_isLoggedIn = user?.uid != null;
});
_isLoggedIn = _firebaseAuth.currentUser?.uid != null;
return _isLoggedIn ?? false;
}
else {
return _isLoggedIn ?? false;
}
...

I need your help for an error I encounter in flutter dart

I have an application and I created a legin and logout page... and when I click on my application's logout button, I get an error like this " Null check operator used on a null value"*and when I point to the error, it tells me [1] :
https://i.stack.imgur.com/n0uJ8.pngentrez
import 'dart:async';
import 'dart:convert';
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:logger/logger.dart';
import '../db/db_auth_shared_preference.dart';
import '../network/app_urls.dart';
import '../models/auth.dart';
enum Status {
notLoggedIn,
loggedIn,
authenticating,
loggedOut,
notReet,
reseted,
resetting
}
//Help display the logs
var logger = Logger();
class AuthProvider with ChangeNotifier {
Auth? _auth;
Auth get auth => _auth!;
void setAuth(Auth auth) {
_auth = auth;
notifyListeners();
}
bool isAuth() {
if (_auth == null || auth.token == '') {
return false;
}
return true;
}
// Time before the token expires
Timer? _authTimer;
DateTime? _expiryDate;
String? username;
String? password;
// Set the status of the user to Not Logged In at the start of the app
Status _status = Status.notLoggedIn;
Status get status => _status;
// Change the status of the user
set status(Status value) {
_status = value;
notifyListeners();
}
// Log In the user
Future<Map<String, dynamic>> login(String email, String password) async {
Map<String, Object> results;
final Map<String, dynamic> loginData = {
'email': email,
'password': password
};
status = Status.authenticating;
logger.d("--- Authentication ---");
try {
Response response = await post(
Uri.parse(
"${AppUrl.login}? username=${loginData['email']}&password=${loginData['password']}"
),
);
logger.d('Login response : ${response.statusCode}');
// The Request Succeded
if (response.statusCode == 200) {
final Map<String, dynamic> responseData =
json.decode(utf8.decode(response.bodyBytes));
var requestStatus = responseData["status"];
if (requestStatus != 0) {
status = Status.notLoggedIn;
results = {'status': false, 'message': "La Connexion a échoué"};
} else {
// Get the status code of the request
Map<String, dynamic> authData = responseData["utilisateurJson"];
logger.d(authData);
_expiryDate = DateTime.now().add(const Duration(seconds: 3500));
//store user shared pref
Auth authUser = Auth.fromMap(authData,
timeToExpire: _expiryDate,
username: loginData['email'],
password: loginData['password']);
_expiryDate = authUser.expiryDate;
logger.wtf(_expiryDate);
//clear session data
AuthPreferences().removeAuth();
//store User session
AuthPreferences().saveAuth(authUser);
setAuth(authUser);
status = Status.loggedIn;
username = loginData["email"];
password = loginData["password"];
results = {
'status': true,
'message': 'Successful login',
'auth': authUser,
};
autoLogOut();
}
} else {
status = Status.notLoggedIn;
results = {'status': false, 'message': 'La Connexion a échoué'};
}
return results;
} catch (e) {
logger.e(e);
status = Status.notLoggedIn;
results = {
'status': false,
'message': "La Connexion avec le serveur a échoué"
};
return results;
} }
void autoLogOut() {
if (_authTimer != null) {
_authTimer!.cancel();
}
final timeToExpiry = _expiryDate!.difference(DateTime.now()).inSeconds;
_authTimer = Timer(Duration(seconds: timeToExpiry),
() async => await login(username!, password!));
}
// Log Out the User
void logOut() {
logger.d("--- User Logging Out ---");
AuthPreferences().removeAuth();
status = Status.loggedOut;
_expiryDate = null;
_auth = null;
logger.d("--- User Logged Out ---");
}
Future<Auth?> tryAutoLogin() async {
final authSession = await AuthPreferences().getAuth();
if (authSession == null) {
return null;
}
logger.d("The expiry time is : ${authSession.expiryDate}");
if (authSession.expiryDate.isBefore(DateTime.now())) {
login(authSession.username, authSession.password);
return authSession;
}
_expiryDate = authSession.expiryDate;
setAuth(authSession);
logger.d("SETTING THE USER");
autoLogOut();
return authSession;
}
}
Error Explanation: Bang operator(!) means that in flutter, when you use this operator, you are completely sure that variable is not going to be null in any case.
There are two ways to resolve it -
Use if conditional to confirm that variable is not null
Use null-aware or if-null operator ?? like
Auth get auth => _auth ?? Auth();
Since you didn't provide any error logs; based on attached image and as your cursor on line no 29, _auth variable is null. So before using ! make sure your variable is not null.

How to display facets with count with Algolia

I'm trying to get the list of facet that I've configured as describe here. I use the new official Algolia package along with the unofficial for settings. I thought that use the official package would change the response. Despite in the console browser, every thing is display as attended the searchResponse.facets is always empty.
Check the code below.
import 'dart:async';
import 'dart:io';
import 'package:algolia/algolia.dart';
import 'package:algolia_helper_flutter/algolia_helper_flutter.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:masterecommerce/src/constants/app_sizes.dart';
import 'package:masterecommerce/src/exceptions/app_exception.dart';
import 'package:masterecommerce/src/features/menu/presentation/search_header.dart';
import 'package:masterecommerce/src/features/products/domain/algolia_output.dart';
import 'package:masterecommerce/src/features/products/domain/algolia_params.dart';
import '../constants/credentials.dart';
import '../features/products/domain/product.dart';
import 'firestore_service.dart';
final searchResponseProvider = StateProvider.autoDispose<SearchResponse>((ref) {
return SearchResponse({});
});
final searchStateProvider = StateProvider.autoDispose<SearchState>((ref) {
return const SearchState(indexName: kIndexName);
});
final algoliaInputProvider = StateProvider.autoDispose<AlgoliaInput>((ref) {
return const AlgoliaInput();
});
final algoliaControllerProvider = StateNotifierProvider.autoDispose<
AlgoliaController, AsyncValue<List<Product>>>((ref) {
return AlgoliaController(
ref: ref, algoliaInput: ref.watch(algoliaInputProvider));
});
final algoliaControllerSearchProvider = StateNotifierProvider.autoDispose<
AlgoliaController, AsyncValue<List<Product>>>((ref) {
return AlgoliaController(
ref: ref,
algoliaInput: AlgoliaInput(
query: ref.watch(currentQuerySearchProvider), hitsPerPage: 3));
});
class AlgoliaController extends StateNotifier<AsyncValue<List<Product>>> {
StreamSubscription? subResponses;
StreamSubscription? subSearchState;
late HitsSearcher searcher;
late Algolia algoliaForSettings;
final Ref ref;
final AlgoliaInput algoliaInput;
AlgoliaController({required this.ref, required this.algoliaInput})
: super(const AsyncLoading()) {
algoliaForSettings = const Algolia.init(
applicationId: algoliaKeyAppId, apiKey: algoliaKeyCustom);
searcher = HitsSearcher(
applicationID: algoliaKeyAppId,
apiKey: algoliaKeyCustom,
indexName: kIndexName,
);
subResponses = searcher.responses.handleError((onError) {
print(onError);
state = AsyncError(onError);
}).listen((searchResponse) {
print(searchResponse.facets);
print(searchResponse.raw["facets"]);
ref.read(searchResponseProvider.state).update((state) => searchResponse);
final products = searchResponse.hits
.map((e) => Product.fromMapAlgolia(e.cast()))
.toList();
if (mounted) {
state = AsyncValue<List<Product>>.data(products);
}
});
subSearchState = searcher.state.handleError((onError) {
print(onError);
state = AsyncError(onError);
}).listen((searchState) {
ref.read(searchStateProvider.state).update((state) => searchState);
});
_newAlgoliaState(algoliaInput: algoliaInput);
}
#override
void dispose() {
searcher.dispose();
subResponses?.cancel();
subSearchState?.cancel();
super.dispose();
}
Future<void> _newAlgoliaState({required AlgoliaInput algoliaInput}) async {
state = const AsyncLoading();
final algoliaOutput = algoliaInput.toAlgoliaOutput();
await _setAlgoliaRanking(algoliaOutput: algoliaOutput);
if (!mounted) {
return;
}
searcher.connectFilterState(algoliaOutput.filterState);
searcher.applyState((state) => algoliaOutput.toSearchState());
}
Future<void> _setAlgoliaRanking(
{required AlgoliaOutput algoliaOutput}) async {
AlgoliaIndexReference algoliaIndexReference =
algoliaForSettings.instance.index("products");
final ranking = algoliaOutput.ranking;
if (ranking != null && ranking.isNotEmpty) {
AlgoliaTask algoliaTask =
await algoliaIndexReference.settings.setRanking([
...ranking,
"typo",
"geo",
"words",
"filters",
"proximity",
"attribute",
"exact",
"custom",
]).setSettings();
await algoliaTask
.waitTask()
.timeout(const Duration(seconds: timeOutSecond))
.catchError((onError) {
if (onError is SocketException) {
throw const AppException.noInternet();
} else if (onError is TimeoutException) {
throw const AppException.timeOut();
} else {
throw const AppException.unknown();
}
});
}
final customRanking = algoliaOutput.customRanking;
if (customRanking != null && customRanking.isNotEmpty) {
final AlgoliaTask algoliaTask = await algoliaIndexReference.settings
.setCustomRanking(customRanking)
.setSettings();
await algoliaTask
.waitTask()
.timeout(const Duration(seconds: timeOutSecond))
.catchError((onError) {
if (onError is SocketException) {
throw const AppException.noInternet();
} else if (onError is TimeoutException) {
throw const AppException.timeOut();
} else {
throw const AppException.unknown();
}
});
}
}
}
As said here the searchState.facet need to be set.

How to setup blocTest for a feature that requires authentication?

So I'm implementing blocTesting for my flutter project and I'm using real apis in testing as that is what I've been asked to do. Apparently when I'm trying out blocTesting for a feature that requires authentication the api is giving back a null response but in the running app it is working fine...
I'm adding the respective files below for the same. Also the name of feature is client and I'm trying to fetch all clients here.
Client_bloc_test.dart
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:injectable/injectable.dart' as inject;
import 'package:mynovatium/app/helper/injections/shared_preference/shared_preference_injection_configuration.dart';
import 'package:mynovatium/features/buy/models/test_model.dart';
import 'package:mynovatium/features/client/bloc/client_bloc.dart';
import 'package:mynovatium/features/client/models/private_client_model.dart';
import 'package:mynovatium/features/login/bloc/authentication/authentication_bloc.dart';
import 'package:mynovatium/features/login/repositories/authentication_repository.dart';
void main() async {
await configureInjection(inject.Environment.test);
final AuthenticationBloc authenticationBloc = AuthenticationBloc();
group('ClientBloc', () {
late PrivateClientModel client;
test('initial state of the bloc is [SignupInitial]', () {
expect(
ClientBloc(authenticationBloc: authenticationBloc).state,
ClientInitial(),
);
});
group('ClientCreateClient', () {
blocTest<ClientBloc, ClientState>(
'emits [ClientLoadInProgress, ClientLoadSuccess] '
'state when successfully fetched clients',
setUp: () async {
client = PrivateClientModel(1, List<TestModel>.empty(), createdAt: DateTime.now(), gender: 'Male', firstName: 'Nikunj', lastName: 'goyal', birthDate: '03/07/2001', ssnr: '0000', email: 'nik#gmail.com', telephoneNumber: '6641234123', street: 'Abcd', zipCode: '6020', city: 'Tyrol');
},
build: () => ClientBloc(authenticationBloc: authenticationBloc),
act: (ClientBloc bloc) => bloc..add(const ClientGetClients(101010)),
expect: () => <dynamic>[
const ClientLoadInProgress(),
],
);
});
});
}
Client_bloc.dart
Future<void> _onGetClients(ClientGetClients event, Emitter<ClientState> emit) async {
// Skip double loadings
if (state is ClientLoadInProgress) return;
PrivateClientModelList _pcml = PrivateClientModelList(<PrivateClientModel>[]);
final PrivateRedeemModel _prm = PrivateRedeemModel(customerId: event.userId, clients: <RedeemClient>[]);
if (state is ClientLoadSuccess) {
final ClientLoadSuccess _currentState = state as ClientLoadSuccess;
_pcml = _currentState.pcml;
try {
emit(const ClientLoadInProgress());
_pcml = await _clientRepository.getClientsForUser(event.userId);
} catch (e) {
final KBMException _exception = e as KBMException;
emit(ClientLoadFailure(exception: _exception));
}
return emit(_currentState.copyWith(pcml: _pcml));
} else {
try {
emit(const ClientLoadInProgress());
_pcml = await _clientRepository.getClientsForUser(event.userId);
for (final PrivateClientModel _client in _pcml.data) {
_prm.clients.add(RedeemClient(clientId: _client.id, quantity: 0));
}
} catch (e) {
final KBMException _exception = e as KBMException;
emit(ClientLoadFailure(exception: _exception));
}
return emit(ClientLoadSuccess(_pcml, _prm));
}
}
In the above code when 'getClientsForUser' is being called the response is null.

The argument type 'RemoteMessage' can't be assigned to the parameter type 'Map<String?, dynamic>'

I am quite new to flutter. Can anybody suggest a solution for the error "The argument type 'RemoteMessage' can't be assigned to the parameter type 'Map<String?, dynamic>'" that I am gettin in my code. Line:20 & line 25 / pushNotificationService.dart.
Thank you
My code is given below:
main.dart
import 'package:driver/AllScreens/carInfoScreen.dart';
import 'package:driver/configMaps.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:driver/AllScreens/mainScreen.dart';
import 'package:driver/AllScreens/registrationScreen.dart';
import 'package:driver/DataHandler/appData.dart';
import 'AllScreens/loginScreen.dart';
Future<void> backgroundHandler(RemoteMessage message) async
{
print(message.data.toString());
print(message.notification!.title);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
currentFirebaseUser = FirebaseAuth.instance.currentUser;
runApp(MyApp());
}
DatabaseReference usersRef = FirebaseDatabase.instance.reference().child("users");
DatabaseReference driversRef = FirebaseDatabase.instance.reference().child("drivers");
DatabaseReference newRequestRef = FirebaseDatabase.instance.reference().child("Ride Requests");
DatabaseReference rideRequestRef = FirebaseDatabase.instance.reference().child("drivers").child(currentFirebaseUser!.uid).child("newRide");
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => AppData(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Driver',
theme: ThemeData(
primarySwatch: Colors.green,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
initialRoute: FirebaseAuth.instance.currentUser == null ? LoginScreen.idScreen : MainScreen.idScreen,
routes: {
RegistrationScreen.idScreen: (context) => RegistrationScreen(),
LoginScreen.idScreen: (context) => LoginScreen(),
MainScreen.idScreen: (context) => MainScreen(),
CarInfoS`enter code here`creen.idScreen: (context) => CarInfoScreen(),
},
),
);
}
}
pushNotification.dart
import 'package:driver/Models/rideDetails.dart';
import 'package:driver/configMaps.dart';
import 'package:driver/main.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:io' show Platform;
class PushNotificationService {
final FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
Future initialize(context) async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
retrieveRideRequestInfo(getRideRequestId(message));
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
retrieveRideRequestInfo(getRideRequestId(message));
});
}
Future<String?> getToken() async {
String? token = await firebaseMessaging.getToken();
driversRef.child(currentFirebaseUser!.uid).child("token").set(token);
firebaseMessaging.subscribeToTopic("alldrivers");
firebaseMessaging.subscribeToTopic("allusers");
}
String getRideRequestId(Map<String?, dynamic> message) {
String rideRequestId = "";
if (Platform.isAndroid) {
rideRequestId = message['data']['ride_request_id'];
} else {
rideRequestId = message['ride_request_id'];
}
return rideRequestId;
}
void retrieveRideRequestInfo(String rideRequestId) {
newRequestRef.child(rideRequestId).once().then((DataSnapshot dataSnapshot) {
if (dataSnapshot.value != null) {
double pickupLocationLat =
double.parse(dataSnapshot.value['pickup']['latitude'].toString());
double pickupLocationLng =
double.parse(dataSnapshot.value['pickup']['longitude'].toString());
String pickupAddress = dataSnapshot.value['pickup_address'].toString();
double dropoffLocationLat =
double.parse(dataSnapshot.value['dropoff']['latitude'].toString());
double dropoffLocationLng =
double.parse(dataSnapshot.value['dropoff']['longitude'].toString());
String dropoffAddress =
dataSnapshot.value['dropoff_address'].toString();
String paymentMethod = dataSnapshot.value['payment_method'].toString();
String rider_name = dataSnapshot.value["rider_name"].toString();
String rider_phone = dataSnapshot.value["rider_phone"].toString();
RideDetails rideDetails = RideDetails();
rideDetails.ride_request_id = rideRequestId;
rideDetails.pickup_address = pickupAddress;
rideDetails.dropoff_address = dropoffAddress;
rideDetails.pickup = LatLng(pickupLocationLat, pickupLocationLng);
rideDetails.dropoff = LatLng(dropoffLocationLat, dropoffLocationLng);
rideDetails.payment_method = paymentMethod;
rideDetails.rider_name = rider_name;
rideDetails.rider_phone = rider_phone;
print("Information :: ");
print(rideDetails.pickup_address);
print(rideDetails.dropoff_address);
}
});
}
}
rideDetails.dart
import 'package:google_maps_flutter/google_maps_flutter.dart';
class RideDetails {
String? pickup_address;
String? dropoff_address;
LatLng? pickup;
LatLng? dropoff;
String? ride_request_id;
String? payment_method;
String? rider_name;
String? rider_phone;
RideDetails({this.pickup_address,this.dropoff_address, this.pickup, this.dropoff, this.ride_request_id, this.payment_method, this.rider_name, this.rider_phone});
}
From,
String getRideRequestId(Map<String?, dynamic> message) {}
To,
String getRideRequestId(var message) {}
For print request in console,
Try This,
if (Platform.isAndroid) {
rideRequestId = message.data['ride_request_id'];
} else {
rideRequestId = message['ride_request_id'];
}
print("Print Notification Data:" + rideRequestId);
return rideRequestId;
}