how to show loader until token is not checked in flutter? - node.js

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MultiProvider(providers: [
ChangeNotifierProvider(
create: (context) => UserProvider(),
)
], child: const MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final AuthService authService = AuthService();
#override
void initState() {
super.initState();
authService.getUserData(context);
setState(() {});
}
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'verdent',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Provider.of<UserProvider>(context).user.token.isNotEmpty
? Provider.of<UserProvider>(context).user.type == 'user'
? BottomNavScreen()
: const AdminScreen()
: const login_a(),
);
}
}
Loader
import 'package:flutter/material.dart';
class Loader extends StatelessWidget {
const Loader({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const Center(
child: CircularProgressIndicator(),
);
}
}
authservice.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:verdent/Dashboard/Home/Screens/Bottom_Nav_bar.dart';
import 'package:verdent/Registraion/Screens/Login_a.dart';
import 'package:verdent/admin_screen.dart';
import 'package:verdent/global_constants.dart';
import 'package:verdent/models/user.dart';
import 'package:verdent/user_provider.dart';
class AuthService {
// sign up user
void signUpUser({
required BuildContext context,
required String email,
required double phone,
required String password,
required String name,
}) async {
try {
User user = User(
id: '',
name: name,
password: password,
email: email,
phone: phone,
type: '',
token: '',
);
http.Response res = await http.post(
Uri.parse('$uri/api/signup'),
body: user.toJson(),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
httpErrorHandling(
response: res,
context: context,
onSuccess: () {
showSnackBar(
context,
'Account created! Login with the same credentials!',
);
},
);
} catch (e) {
showSnackBar(context, e.toString());
}
}
// sign in user
void signInUser({
required BuildContext context,
required double phone,
required String password,
}) async {
try {
http.Response res = await http.post(
Uri.parse('$uri/api/signin'),
body: jsonEncode({
'phone': phone,
'password': password,
}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
httpErrorHandling(
response: res,
context: context,
onSuccess: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
// ignore: use_build_context_synchronously
Provider.of<UserProvider>(context, listen: false).setUser(res.body);
await prefs.setString(
'x-auth-token', jsonDecode(res.body)['token']);
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Provider.of<UserProvider>(context, listen: false)
.user
.type ==
'user'
? BottomNavScreen()
: const AdminScreen()));
});
} catch (e) {
showSnackBar(context, e.toString());
}
}
// get user data
void getUserData(
BuildContext context,
) async {
try {
var userProvider = Provider.of<UserProvider>(context, listen: false);
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('x-auth-token');
if (token == null) {
prefs.setString('x-auth-token', '');
}
var tokenRes = await http.post(
Uri.parse('$uri/tokenIsValid'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'x-auth-token': token!
},
);
var response = jsonDecode(tokenRes.body);
if (response == true) {
http.Response userRes = await http.get(
Uri.parse('$uri/'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'x-auth-token': token
},
);
userProvider.setUser(userRes.body);
}
} catch (e) {
showSnackBar(context, e.toString());
}
}
void logOut(BuildContext context) async {
try {
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
await sharedPreferences.setString('x-auth-token', '');
// ignore: use_build_context_synchronously
Navigator.push(
context, MaterialPageRoute(builder: (context) => const login_a()));
} catch (e) {
showSnackBar(context, e.toString());
}
}
}
when logged in user tries to enter app or restart app they first goes to login page then redirected to homepage how to show loader until token is checked if user is not logged in then stays at login page otherwise goes back to homepage. please help me to solve this issue due to this user-expirence of my app is downgraded.

create bool variable for checking loading status. For example, isLoading and default value is true.
in your main initState function, add change isLoading to false after call any functions that you want to setup before show a screen to user.
setState(() {
authService.getUserData(context);
isLoading = false;
});
in build function, add turnary operator to check is state loading or not. If still loading, show Loader. If not, show your desired page.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'verdent',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: isLoading ? Loader() : Provider.of<UserProvider>(context).user.token.isNotEmpty
? Provider.of<UserProvider>(context).user.type == 'user'
? BottomNavScreen()
: const AdminScreen()
: const login_a(),
);
}

Related

I cant access as an "user" on MongoDB

This is my issue, I can access to MongoDB as an admin, but when I switch to “user” I can't, and it shows a message like this: msg: "You are not an admin!", even though I switched to 'user', this is and screenshot on MongoDB:
MongoDB, please click to see the image
This is a screenshot of the app message error:
Flutter app, please click to see the image
This is my code:
admin.js
const jwt = require("jsonwebtoken"); const User = require("../models/user");
const admin = async (req, res, next) => { try {
const token = req.header("x-auth-token");
if (!token)
return res.status(401).json({ msg: "No auth token, access denied" });
const verified = jwt.verify(token, "passwordKey");
if (!verified)
return res
.status(401)
.json({ msg: "Token verification failed, authorization denied." });
const user = await User.findById(verified.id);
if (user.type == "user" || user.type == "seller") {
return res.status(401).json({ msg: "You are not an admin!" });
}
req.user = verified.id;
req.token = token;
next(); } catch (err) {
res.status(500).json({ error: err.message }); } };
module.exports = admin;
admin_services.dart
class AdminServices {
void sellProduct({
required BuildContext context,
required String name,
required String description,
required double price,
required double quantity,
required String category,
required List<File> images,
}) async {
final userProvider = Provider.of<UserProvider>(context, listen: false);
try {
final cloudinary = CloudinaryPublic('blur', 'blur');
List<String> imageUrls = [];
for (int i = 0; i < images.length; i++) {
CloudinaryResponse res = await cloudinary
.uploadFile(CloudinaryFile.fromFile(images[i].path, folder: name));
imageUrls.add(res.secureUrl);
}
Product product = Product(
name: name,
description: description,
quantity: quantity,
images: imageUrls,
category: category,
price: price,
);
http.Response res = await http.post(
Uri.parse('$uri/admin/add-product'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'x-auth-token': userProvider.user.token,
},
body: product.toJson(),
);
httpErrorHandle(
response: res,
context: context,
onSuccess: () {
showSnackBar(context, 'Product added successfully');
Navigator.pop(context);
},
);
} catch (e) {
showSnackBar(context, e.toString());
}
}
Future<List<Product>> fetchAllProducts(BuildContext context) async {
final userProvider = Provider.of<UserProvider>(context, listen: false);
List<Product> productList = [];
try {
http.Response res = await http.get(
Uri.parse('$uri/admnin/get-products'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'x-auth-token': userProvider.user.token,
},
);
httpErrorHandle(
response: res,
context: context,
onSuccess: () {
for (int i = 0; i < jsonDecode(res.body).length; i++) {
productList.add(
Product.fromJson(
jsonEncode(
jsonDecode(res.body)[i],
),
),
);
}
});
} catch (e) {
showSnackBar(context, e.toString());
}
return productList;
}
void deleteProduct(
{required BuildContext context,
required Product product,
required VoidCallback onSuccess}) async {
final userProvider = Provider.of<UserProvider>(context, listen: false);
try {
http.Response res = await http.post(
Uri.parse('$uri/admnin/delete-product'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'x-auth-token': userProvider.user.token,
},
body: jsonEncode(
{
'id': product.id,
},
),
);
httpErrorHandle(
response: res,
context: context,
onSuccess: () {
onSuccess();
},
);
} catch (e) {
showSnackBar(context, e.toString());
}
}
}
Hope you can help me, thanks for your attention

Bug when trying to fetch data from node.js api to flutter

I have searched for a solution but couldn't find any, basically when I search for an account inside the app it shows up and looking fine but when I press it to get to the profile details screen it keeps loading and it seems to never get the data.
Below is the code for the response
import 'dart:convert';
ResponseUserSearch responseUserSearchFromJson(String str) => ResponseUserSearch.fromJson(json.decode(str));
String responseUserSearchToJson(ResponseUserSearch data) => json.encode(data.toJson());
class ResponseUserSearch {
ResponseUserSearch({
required this.resp,
required this.message,
required this.anotherUser,
required this.analytics,
required this.postsUser,
required this.isFriend,
required this.isPendingFollowers
});
bool resp;
String message;
AnotherUser anotherUser;
Analytics analytics;
List<PostsUser> postsUser;
int isFriend;
int isPendingFollowers;
factory ResponseUserSearch.fromJson(Map<String, dynamic> json) => ResponseUserSearch(
resp: json["resp"],
message: json["message"],
anotherUser: AnotherUser.fromJson(json["anotherUser"]),
analytics: Analytics.fromJson(json["analytics"]),
postsUser: List<PostsUser>.from(json["postsUser"].map((x) => PostsUser.fromJson(x))),
isFriend: json["is_friend"],
isPendingFollowers: json["isPendingFollowers"]
);
Map<String, dynamic> toJson() => {
"resp": resp,
"message": message,
"anotherUser": anotherUser.toJson(),
"analytics": analytics.toJson(),
"postsUser": List<dynamic>.from(postsUser.map((x) => x.toJson())),
"is_friend": isFriend,
"isPendingFollowers": isPendingFollowers
};
}
class Analytics {
Analytics({
required this.posters,
required this.friends,
required this.followers,
});
int posters;
int friends;
int followers;
factory Analytics.fromJson(Map<String, dynamic> json) => Analytics(
posters: json["posters"],
friends: json["friends"],
followers: json["followers"],
);
Map<String, dynamic> toJson() => {
"posters": posters,
"friends": friends,
"followers": followers,
};
}
class AnotherUser {
AnotherUser({
required this.uid,
required this.fullname,
required this.phone,
required this.image,
required this.cover,
required this.birthdayDate,
required this.createdAt,
required this.username,
required this.description,
required this.isPrivate,
required this.email,
});
String uid;
String fullname;
String phone;
String image;
String cover;
dynamic birthdayDate;
DateTime createdAt;
String username;
String description;
int isPrivate;
String email;
factory AnotherUser.fromJson(Map<String, dynamic> json) => AnotherUser(
uid: json["uid"],
fullname: json["fullname"],
phone: json["phone"] ?? '',
image: json["image"] ?? '',
cover: json["cover"] ?? '',
birthdayDate: DateTime.parse(json["birthday_date"] ?? '2021-10-22T20:17:53'),
createdAt: DateTime.parse(json["created_at"] ?? '2021-10-22T20:17:53'),
username: json["username"],
description: json["description"] ?? '',
isPrivate: json["is_private"],
email: json["email"],
);
Map<String, dynamic> toJson() => {
"uid": uid,
"fullname": fullname,
"phone": phone,
"image": image,
"cover": cover,
"birthday_date": birthdayDate,
"created_at": createdAt.toIso8601String(),
"username": username,
"description": description,
"is_private": isPrivate,
"email": email,
};
}
class PostsUser {
PostsUser({
required this.postUid,
required this.isComment,
required this.typePrivacy,
required this.createdAt,
required this.images
});
String postUid;
int isComment;
String typePrivacy;
DateTime createdAt;
String images;
factory PostsUser.fromJson(Map<String, dynamic> json) => PostsUser(
postUid: json["post_uid"],
isComment: json["is_comment"],
typePrivacy: json["type_privacy"],
createdAt: DateTime.parse(json["created_at"]),
images: json["images"],
);
Map<String, dynamic> toJson() => {
"post_uid": postUid,
"is_comment": isComment,
"type_privacy": typePrivacy,
"created_at": createdAt.toIso8601String(),
"images": images,
};
}
below is the profile page where I call that data
class ProfileAnotherUserPage extends StatefulWidget {
final String idUser;
const ProfileAnotherUserPage({Key? key, required this.idUser}) : super(key: key);
#override
State<ProfileAnotherUserPage> createState() => _ProfileAnotherUserPageState();
}
class _ProfileAnotherUserPageState extends State<ProfileAnotherUserPage> {
#override
Widget build(BuildContext context) {
return BlocListener<UserBloc, UserState>(
listener: (context, state) {
if( state is LoadingFollowingUser ){
modalLoading(context, 'Duke u ngarkuar...');
}else if( state is FailureUserState ){
Navigator.pop(context);
errorMessageSnack(context, state.error);
}else if( state is SuccessFollowingUser ){
Navigator.pop(context);
setState(() {});
}
},
child: Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: FutureBuilder<ResponseUserSearch>(
future: userService.getAnotherUserById(widget.idUser),
builder: (context, snapshot) {
return !snapshot.hasData
? const _LoadingDataUser()
: _BodyUser(responseUserSearch: snapshot.data!);
},
),
),
),
);
}
}
class _BodyUser extends StatelessWidget {
final ResponseUserSearch responseUserSearch;
const _BodyUser({ Key? key, required this.responseUserSearch }) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView(
physics: const BouncingScrollPhysics(),
children: [
_CoverAndProfile(user: responseUserSearch.anotherUser),
const SizedBox(height: 10.0),
_UsernameAndDescription(user: responseUserSearch.anotherUser),
const SizedBox(height: 30.0),
_PostAndFollowingAndFollowers(analytics: responseUserSearch.analytics),
const SizedBox(height: 30.0),
_BtnFollowAndMessage(
isFriend: responseUserSearch.isFriend,
uidUser: responseUserSearch.anotherUser.uid,
isPendingFollowers: responseUserSearch.isPendingFollowers,
username: responseUserSearch.anotherUser.username,
avatar: responseUserSearch.anotherUser.image,
),
const SizedBox(height: 20.0),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
height: 46,
child: Column(
children: [
const Icon(Icons.grid_on_rounded, size: 30),
const SizedBox(height: 5.0),
Container(
height: 1,
color: Colors.grey[300],
)
],
),
),
const SizedBox(height: 5.0),
_ListFotosAnotherProfile(
posts: responseUserSearch.postsUser,
isPrivate: responseUserSearch.anotherUser.isPrivate,
isFriend: responseUserSearch.isFriend,
),
],
);
}
}
below is the backend code for this particular problem
export const getAnotherUserById = async (req: Request, res: Response): Promise<Response> => {
try {
const conn = await connect();
const [ userdb ] = await conn.query<RowDataPacket[]>(`CALL SP_GET_USER_BY_ID(?);`, [ req.params.idUser ]);
const posters = await conn.query<RowDataPacket[]>(' SELECT COUNT(person_uid) AS posters FROM posts WHERE person_uid = ?', [req.params.idUser]);
const friends = await conn.query<RowDataPacket[]>('SELECT COUNT(person_uid) AS friends FROM friends WHERE person_uid = ?', [req.params.idUser]);
const followers = await conn.query<RowDataPacket[]>('SELECT COUNT(person_uid) AS followers FROM followers WHERE person_uid = ?', [req.params.idUser]);
const posts = await conn.query<RowDataPacket[]>(`CALL SP_GET_POST_BY_IDPERSON(?);`, [req.params.idUser]);
const isFollowing = await conn.query<RowDataPacket[]>('CALL SP_IS_FRIEND(?,?);', [req.idPerson, req.params.idUser]);
const isPendingFollowers = await conn.query<RowDataPacket[]>(`CALL SP_IS_PENDING_FOLLOWER(?,?)`, [ req.params.idUser, req.idPerson ]);
conn.end();
return res.json({
resp: true,
message: 'Get Another User by id',
anotherUser: userdb[0][0],
analytics: {
'posters' : posters[0][0].posters,
'friends' : friends[0][0].friends,
'followers': followers[0][0].followers
},
postsUser: posts[0][0],
is_friend: isFollowing[0][0][0].is_friend,
isPendingFollowers: isPendingFollowers[0][0][0].is_pending_follower
});
} catch(err) {
return res.status(500).json({
resp: false,
message: err
});
}
}
This is the getAnotherUserById function
Future<ResponseUserSearch> getAnotherUserById(String idUser) async {
final token = await secureStorage.readToken();
final resp = await http.get(Uri.parse('${URLS.urlApi}/user/get-another-user-by-id/'+ idUser),
headers: { 'Accept': 'application/json', 'xxx-token': token! }
);
return ResponseUserSearch.fromJson(jsonDecode(resp.body));
}

How to send a notification for a specific token, flutter, firebase messaging and node.js

I am designing an application and in it I will have a notification system between clients after an onCreate event.
Here is my index.js code
const functions= require("firebase-functions");
const admin =require("firebase-admin");
admin.initializeApp();
var fcm = admin.messaging();
// Node.js e.g via a Firebase Cloud Function
exports.sendPush = functions.firestore.document('notifications/{notificationId}').onCreate((change, context)=>{
const chauffeur = change.after.data().chauffeur;
const date_reception = change.after.data().date_reception;
const send_name = change.after.data().send_name;
const token = change.after.data().token;
console.log('chauffeur' + chauffeur);
console.log('date_reception' + date_reception);
console.log('send_name' + send_name);
console.log('token' + token);
const payload = {
notification:{
title: 'New message',
body: 'Message reçu de' + chauffeur,
sound: "default",
},
data:{
'chauffeur':chauffeur,
'date_reception': date_reception,
'send_name': send_name,
},
}
return admin.messaging().sendToDevice(token, payload);
});
et mon code dart&flutter
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
Future<void> _messageHandler(RemoteMessage message) async {
print('background message ${message.notification!.body}');
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_messageHandler);
runApp(MessagingTutorial());
}
class MessagingTutorial extends StatelessWidget {
static const String idScreen = "note";
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Firebase Messaging',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Firebase Messaging'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late FirebaseMessaging messaging;
String? notificationText;
#override
void initState() {
super.initState();
messaging = FirebaseMessaging.instance;
messaging.getToken().then((value) {
print(value);
});
FirebaseMessaging.onMessage.listen((RemoteMessage event) {
RemoteNotification? notification = event.notification;
AndroidNotification? androidNotification = event.notification!.android;
print("message recieved");
print(event.notification!.body);
print(event.data.values);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Notification ${event.data['title']}"),
content: Text(event.notification!.body!),
actions: [
Row(children: [
TextButton(
child: Text("Annuler"),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text("Ok"),
onPressed: () {
Navigator.of(context).pop();
},
)
])
],
);
});
});
FirebaseMessaging.onMessageOpenedApp.listen((message) {
print('Message clicked!');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
),
body: Center(child: Text("Messaging Tutorial")),
);
}
}
The problem is, when I save in my "notifications" collection, the notification doesn't show even in the background, not even in forground.
After saving in the collection, the number of uses of the function increases but no effect in the application.
usage for the function
When I send the test message from firebase cloud messaging, everything is working fine
Cloud messaging test
I don't know how to fix this, if anyone can help me i would be very happy.
Thank you
There could be a lot of points that fail here. The cold start could cause that you don't wait enought for the notification. When your App is open it won't show anything if you havend written code for it to handle messages while in focus. You could have an outdated notification token. Do you update it on your database?
Can you try it with this shema of the payload to:
const payload = {
notification: {
title: "title",
body: "body",
},
webpush: {
notification: {
title: "title",
body: "body",
},
},
data: {
test: 'test',
},
}

Flutter: How I pass the JWT-Token in headers?

I want to pass Token to headers ("Authorization": "Bearer " +getToken). Otherwise i cannot make a mutation because the user is identified with the token in the headers. Do you have to do anything in the mutation function? E.g. in the mutation function add headers? I use the graphql_flutter package.
Backend: NodeJs - Apollo.
here my code:
main:
import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import './pages/auth_screen.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'pages/auth_add_address_screen.dart';
import './client.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Config.functionGetToken();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
Future<String> getTheToken() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
String token = _prefs.getString("token");
return token;
}
#override
Widget build(BuildContext context) {
return GraphQLProvider(
client: Config.initailizeClient(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
unselectedWidgetColor: Colors.white60,
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: AuthScreen(),
routes: {
AuthAddAddress.routeName: (ctx) => AuthAddAddress(),
AuthScreen.routeName: (ctx) => AuthScreen(),
},
),
);
}
}
client:
import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Config {
static SharedPreferences pref;
static final HttpLink httpLink = HttpLink(
uri: 'http://10.0.2.2:4000/graphql',
headers: {"Authorization": "Bearer " + pref.getString("token")});
static final AuthLink authLink =
AuthLink(getToken: () => pref.getString("token"));
static final Link link = authLink.concat(httpLink);
static String token;
static functionGetToken() async {
pref = await SharedPreferences.getInstance();
}
static ValueNotifier<GraphQLClient> initailizeClient() {
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
cache: OptimisticCache(dataIdFromObject: typenameDataIdFromObject),
link: link,
),
);
return client;
}
}
Here my onPressed() method where i get the token and set it:
onPressed: () async {
if (_authMode == AuthMode.Signup) {
if (_userRegGlobalKey.currentState.validate()) {
var userMutation = runMutation(
{
'email': _emailController.text,
'password': _passwordController.text,
'firstname': _firstnameController.text,
'lastname': _lastnameController.text,
},
);
var result = await userMutation.networkResult;
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.loading) {
return Center(
child: Platform.isAndroid
? CircularProgressIndicator()
: CupertinoActivityIndicator(),
);
} else {
String _token = await result
.data["createUser"]["token"];
String _refreshToken = await result
.data["createUser"]["refreshToken"];
if (_token != null && _refreshToken != null) {
SharedPreferences pref =
await SharedPreferences.getInstance();
pref.setString("token", _token);
pref.setString("refreshToken", _refreshToken);
print(_token);
print(_refreshToken);
Navigator.of(context)
.pushNamed(AuthAddAddress.routeName);
}
}
}
}
},

Flutter JSON data issue

I'm facing issue to fetch json data from Flutter mobile app.
Code as follow:
import 'package:flutter/material.dart';
import 'package:flutter_app/pages/main_page.dart';
class App extends StatelessWidget
{
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Flutter NodeJS",
home: MainPage(),
);
}
}
void main(){
runApp(App());
}
main_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_app/modules/http.dart';
import 'package:flutter_app/pages/add_user_page.dart';
class MainPage extends StatefulWidget
{
#override
State<StatefulWidget> createState() {
return MainPageState();
}
}
class User
{
String id;
String first_name,email;
User(this.id, this.first_name,this.email);
}
class MainPageState extends State<MainPage>
{
List<User> users = [];
Future<void> refreshUsers()async{
var result = await http_get('users');
if(result.ok)
{
setState(() {
users.clear();
var in_users = result.data as List<dynamic>;
in_users.forEach((in_user){
users.add(User(
in_user['id'].toString(),
in_user['first_name'],
in_user['email']
));
});
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Users"),
//email: Text("Email"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: (){
Navigator.of(context).push(MaterialPageRoute(
builder: (context){
return AddUserPage();
}
));
},
)
],
),
body: RefreshIndicator(
onRefresh: refreshUsers,
child: ListView.separated(
itemCount: users.length,
itemBuilder: (context, i) => ListTile(
leading: Icon(Icons.person),
title: Text(users[i].first_name+"\n" + users[i].email),
//email: Text(users[i].email),
),
separatorBuilder: (context, i) => Divider(),
),
),
);
}
}
http.dart
import 'dart:convert';
import "package:http/http.dart" as http;
class RequestResult
{
bool ok;
dynamic data;
RequestResult(this.ok, this.data);
}
//'https://jsonplaceholder.typicode.com/users/1
//http://192.168.183.179:8081/api/users/
const PROTOCOL = "http";
const DOMAIN = "https://jsonplaceholder.typicode.com/users/1";
Future<RequestResult> http_get(String route, [dynamic data]) async
{
var dataStr = jsonEncode(data);
var url = "$PROTOCOL://$DOMAIN/$route?data=$dataStr";
var result = await http.get(url);
return RequestResult(true, jsonDecode(result.body));
}
Future<RequestResult> http_post(String route, [dynamic data]) async
{
var url = "$PROTOCOL://$DOMAIN/$route";
var dataStr = jsonEncode(data);
var result = await http.post(url, body: dataStr, headers:{"Content-Type":"application/json"});
return RequestResult(true, jsonDecode(result.body));
}
When I'm fetch json data from "https://jsonplaceholder.typicode.com/users/1". Its working fine.
enter image description here
When I try to fetch json data from "https://192.168.183.179:8081/api/users". Its give error:
at Object.createErrorWithStack (http://localhost:15340/dart_sdk.js:4348:12)
at Object._rethrow (http://localhost:15340/dart_sdk.js:37892:16)
at async._AsyncCallbackEntry.new.callback (http://localhost:15340/dart_sdk.js:37886:13)
at Object._microtaskLoop (http://localhost:15340/dart_sdk.js:37718:13)
at _startMicrotaskLoop (http://localhost:15340/dart_sdk.js:37724:13)
at http://localhost:15340/dart_sdk.js:33243:9
What I'm doing wrong
Regards,
SAO
Check in Postman whether the ip address is returning data.
Another case would be the data obtained, could not be transffered correctly to the app. Check the variables and types where the data is stored.

Resources