adding token with the url string concatenation - flutter

hi I want to send token with my api url i tried it by concatenate the token with api url but not. it's showing the error you cannot call the value on null. i cannot figure it out. any help from your side should be appreciate.
This is my api code:
class APIService {
String baseurl = "https://b2all.live/api";
var log = Logger();
FlutterSecureStorage storage = FlutterSecureStorage();
//old get
Future get(String url) async {
await storage.read(key: "api_token");
url = formater(url);
// /user/register
var response = await http.get(
url,
);
if (response.statusCode == 200) {
log.i(response.body);
return json.decode(response.body);
}
log.i(response.body);
log.i(response.statusCode);
}
String formater (String url) {
return baseurl+url;
}
}
And this is my fetching data from api code:
#override
void initState() {
super.initState();
fetchData();
}
void fetchData() async {
var preferences = await SharedPreferences.getInstance();
String api_token = preferences.getString('api_token');
print(api_token);
var response = await networkHandler.get(
"/profile/DvIXUN1CAgYMQzKri0dx3XVxfcABDjbPEg1QyHVD4vu1pQM8pRF56OjLgVW8");
setState(() {
profileModelFix = ProfileModelFix.fromJson(response);
circular = false;
});
}
this is my model file. it's showing error on model. but i cannot figure it out. any help from your side will be helpful for me.
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'profileModelFix.g.dart';
#JsonSerializable()
class ProfileModelFix {
String name;
String user_name;
String dob;
String phone;
String gender;
String bio;
String api_token;
ProfileModelFix ({
this.name, this.user_name, this.dob, this.phone, this.gender, this.bio, this.api_token,
});
factory ProfileModelFix.fromJson(Map<String,dynamic> json) =>
_$ProfileModelFixFromJson(json);
Map<String,dynamic> toJson() => _$ProfileModelFixToJson(this);
}

Related

flutter search from API Json

Im trying to make a searchbar that fetch data from mysql , but i have a problem that when i call data fetch function it returns
Instance of '_Future<List>'
this is my code
Future<List<Students>> getStudents(String id) async {
var url = 'http://localhost/getStudents.php';
final response = await http.post(Uri.parse(url), body: {
'id':id,
});
var res = jsonDecode(response.body)['fname'] as List;
if (response.statusCode == 200) {
return res.map((std) => Students.fromJson(std)).toList();
}else {
throw Exception('Failed to load shows');
}
}
my class :
class Students{
final int id;
final String fname;
final String sname;
final String tname;
const Students( {
required this.id,
required this.sname,
required this.tname,
required this.fname,
});
factory Students.fromJson(Map<String, dynamic> json) => Students(
id: json['Id'],
sname: json['secname'],
tname:json['thirdname'] ,
fname: json['firstname'],
);
}
getStudents is a future function and you need to await for it:
List<Students> result = await getStudents('');

How to access token saved as a variable in different dart page in a secured storage

I have saved a token as a variable in flutter secure storage in a file called login_response_model.dart and I am trying to access it in the home screen, but I keep getting error as undefined name:
Here is the login_response_model.dart:
class LoginResponse {
dynamic? key;
List<dynamic>? non_field_errors;
LoginResponse({this.key, this.non_field_errors});
factory LoginResponse.fromJson(mapOfBody) {
return LoginResponse(
key: mapOfBody['key'],
non_field_errors: mapOfBody['non_field_errors'],
);
}
}
LoginResponseModel loginResponseJson(String str) =>
LoginResponseModel.fromJson(json.decode(str));
class LoginResponseModel {
dynamic? key;
List<dynamic>? non_field_errors;
LoginResponseModel({this.key, this.non_field_errors});
LoginResponseModel.fromJson(mapOfBody) {
key:
mapOfBody['key'];
non_field_errors:
mapOfBody['non_field_errors'];
print(mapOfBody['key']);
// Create storage
final storage = new FlutterSecureStorage();
// Write value
storage.write(key: 'Token', value: mapOfBody['key']);
}
Map<String, dynamic> toJson() {
final _data = <String, dynamic>{};
_data['key'] = key;
_data['non_field_errors'] = non_field_errors;
return _data;
}
}
class Data {
Data({
required this.username,
required this.email,
required this.date,
required this.id,
required this.key,
});
late final String username;
late final String email;
late final String date;
late final String id;
late final String key;
Data.fromJson(Map<String, dynamic> json) {
username = json['username'];
email = json['email'];
date = json['date'];
id = json['id'];
key = json['key'];
}
Map<String, dynamic> toJson() {
final _data = <String, dynamic>{};
_data['username'] = username;
_data['email'] = email;
_data['date'] = date;
_data['id'] = id;
_data['key'] = key;
return _data;
}
}
Here is the homescreen:
Future<User> fetchUser() async {
var url = Uri.parse(Config.apiURL + Config.userProfileAPI);
var value = storage.read(key: 'Token');
My question:
How can I access the token saved in a secured storage into the home screen?
Is there an easier and more secure way to access the token saved other than the way I have arranged it?
Use can you SharedPreference & save token here. Each time you want to use, you just need to:
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString("key_token") ?? "";
However, each time you want to use it, you again need to use async function & wait until it give you saved token. Although it doesn't take so much time & space but we need to notice this. You can init a global variable to save token whenever open app or login success. Learn more about Singleton.
Example in my app: data_instance.dart
class DataInstance {
static DataInstance _instance = new DataInstance.internal();
DataInstance.internal();
factory DataInstance() => _instance;
late String accessToken;
initPreference() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
DataInstance().accessToken = prefs.getString("key_token_haha")?? '';
}
}
In main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await DataInstance().initPreference();
runApp(const MyApp());
}

Error fetching API / A value of type 'List<Heroes>' can't be returned from the method 'getHeroes' because has a return type of 'Future<List<String>?>

im new in Dart/Flutter and im struggling with consuming API, here is my file thats inside my model folder:
List<Heroes> heroesFromJson(String str) =>
List<Heroes>.from(json.decode(str).map((x) => Heroes.fromJson(x)));
String heroesToJson(List<Heroes> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Heroes {
Heroes({
required this.id,
required this.name,
required this.localizedName,
required this.primaryAttr,
required this.attackType,
required this.roles,
});
int id;
String name;
String localizedName;
String primaryAttr;
String attackType;
List<String> roles;
factory Heroes.fromJson(Map<String, dynamic> json) => Heroes(
id: json["id"],
name: json["name"],
localizedName: json["localized_name"],
primaryAttr: json["primary_attr"],
attackType: json["attack_type"],
roles: List<String>.from(json["roles"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"localized_name": localizedName,
"primary_attr": primaryAttr,
"attack_type": attackType,
"roles": List<dynamic>.from(roles.map((x) => x)),
};
}
And here is where im getting the error, inside services folder:
class DotaServices {
Future<List<String>?> getHeroes() async {
var client = http.Client();
var url = Uri.parse('https://api.opendota.com/api/heroes');
var response = await client.get(url);
if (response.statusCode == 200) {
var json = response.body;
return heroesFromJson(json);
}
}
}
The error is occuring in that line:
return heroesFromJson(json);
And the message that appears is:
A value of type 'List<Heroes>' can't be returned from the method 'getHeroes' because it has a return type of 'Future<List<String>?>'.
how to solve it? Im struggling real hard on this :/
Your method returns a list of heroes... so... you need to return a list of heroes:
Future<List<String>?> getHeroes() async {
needs to be
Future<List<Heroes>?> getHeroes() async {
heroesFromJson returns a list of heroes so getHeroes has to return a list of heroes:
Future<List<Heroes>?> getHeroes()
Also, your method heroesFromJson returns a List<Heroes> not nullable, but your method getHeroes() return a List<Heroe>? which is nullable.
You either can make your return from heroesFromJson a nullable list List<T>? or your return from getHeroes() a non-nullable list List
Be careful making your List nullable or non-nullable List<Hero>?, not your Hero List<Hero?>
It seems to me that such code should work more reliably.
return Hero.fromJsonList(json as List);
This small example (including function main) was generated with a very small script.
import 'dart:convert';
import 'package:http/http.dart' as http;
void main(List<String> args) async {
final svc = DotaServices();
final heroes = await svc.getHeroes();
print('Heroes: ${heroes.length}');
}
class DotaServices {
Future<List<Hero>> getHeroes() async {
final client = http.Client();
final url = Uri.parse('https://api.opendota.com/api/heroes');
final response = await client.get(url);
if (response.statusCode == 200) {
final source = response.body;
final json = jsonDecode(source);
return Hero.fromJsonList(json as List);
}
throw StateError('Http error: ${response.statusCode}');
}
}
class Hero {
Hero(
{required this.id,
required this.name,
required this.localizedName,
required this.primaryAttr,
required this.attackType,
required this.roles});
factory Hero.fromJson(Map json) {
return Hero(
id: json['id'] as int,
name: json['name'] as String,
localizedName: json['localized_name'] as String,
primaryAttr: json['primary_attr'] as String,
attackType: json['attack_type'] as String,
roles: json['roles'] == null
? []
: (json['roles'] as List).map((e) => e as String).toList(),
);
}
final int id;
final String name;
final String localizedName;
final String primaryAttr;
final String attackType;
final List<String> roles;
static List<Hero> fromJsonList(List json) {
return json.map((e) => Hero.fromJson(e as Map)).toList();
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'localized_name': localizedName,
'primary_attr': primaryAttr,
'attack_type': attackType,
'roles': roles,
};
}
static List<Map<String, dynamic>> toJsonList(List<Hero> list) {
return list.map((e) => e.toJson()).toList();
}
}
Using this codegen script you can generate the models and serializers.
It also generates a working example.
import 'dart:io';
import 'package:object_serializer/json_serializer_generator.dart';
import 'package:yaml/yaml.dart';
void main() {
final classes = loadYaml(_classes) as Map;
final g = JsonSerializerGenerator();
final classesCode = g.generateClasses(classes);
final values = {
'classes': classesCode,
};
var source = g.render(_template, values);
source = g.format(source);
File('bin/stackoverflow.dart').writeAsStringSync(source);
}
const _classes = '''
Hero:
fields:
id: int
name: String
localizedName: {type: String, alias: localized_name}
primaryAttr: {type: String, alias: primary_attr}
attackType: {type: String, alias: attack_type}
roles: List<String>
''';
const _template = r'''
import 'dart:convert';
import 'package:http/http.dart' as http;
void main(List<String> args) async {
final svc = DotaServices();
final heroes = await svc.getHeroes();
print('Heroes: ${heroes.length}');
}
class DotaServices {
Future<List<Hero>> getHeroes() async {
final client = http.Client();
final url = Uri.parse('https://api.opendota.com/api/heroes');
final response = await client.get(url);
if (response.statusCode == 200) {
final source = response.body;
final json = jsonDecode(source);
return Hero.fromJsonList(json as List);
}
throw StateError('Http error: ${response.statusCode}');
}
}
{{classes}}
''';

I have an error like the non-nullable variable 'sessionUser' must be initialized

I have an error like:
The non-nullable variable 'sessionUser' must be initialized. try adding an initializer expression...
I searched a lot on the net but I did not find a solution to my problem. Can you help me to solve this problem?
import 'dart:convert';
import 'package:flutter/widgets.dart';
import 'package:shared_preferences/shared_preferences.dart';
class UserModel {
String id;
String nom;
String email;
UserModel({
required this.id,
required this.nom,
required this.email
});
static UserModel sessionUser;
factory UserModel.fromJson(Map<String,dynamic> i) => UserModel(
id: i['id'],
nom: i['nom'],
email: i['email']
);
Map<String,dynamic> toMap() => {
"id": id,
"nom": nom,
"email": email
};
static void saveUser(UserModel user) async {
SharedPreferences pref = await SharedPreferences.getInstance();
var data = json.encode(user.toMap());
pref.setString("user", data);
pref.commit();
}
static void getUser() async {
SharedPreferences pref = await SharedPreferences.getInstance();
var data = pref.getString("user");
if (data != null) {
var decode = json.decode(data);
var user = await UserModel.fromJson(decode);
sessionUser = user;
} else {
sessionUser = UserModel();
}
}
static void logOut() async {
SharedPreferences p = await SharedPreferences.getInstance();
p.setString("user", null);
sessionUser = null;
p.commit();
}
}
your variable sessionUser is not initialized. Try something like this :
static UserModel? sessionUser;
The ? means the variable can be null, so you'll have to check if the variable is null before using later in your code.

About Firebase real time database

I am working on Firebase real time databases in Flutter. I am storing user information and their corresponding data in database. My code is given below:
//User Auth Class
class UserAuth{
final String id;
final String email;
final String token;
UserAuth({#required this.id, #required this.email, #required this.token});
}
//User Details Class for storing data of corresponding user
class UserDetails{
final String userDetailsId;
final String name;
final String email;
UserDetails({#required this.userDetailsId,#required this.name, #required this.email});
}
//I am using this code to add userDetails in database.
List<UserDetails> _detailsList = [];
UserDetails _details;
Future<bool> addUserDetails(String username, String email) async {
_isLoading = true;
notifyListeners();
final Map<String, dynamic> userDetails = {
'username': username,
'email': email,
};
try {
final http.Response response = await http.post(
'https://intro-to-firebase-711d4.firebaseio.com/Users.json',
body: json.encode(userDetails));
if (response.statusCode != 200 && response.statusCode != 201) {
_isLoading = false;
notifyListeners();
return false;
}
final Map<String, dynamic> responseData = json.decode(response.body);
_details = UserDetails(
userDetailsId: responseData['name'], name: username, email: email);
_detailsList.add(_details);
_isLoading = false;
notifyListeners();
return true;
} catch (error) {
_isLoading = false;
notifyListeners();
return false;
}
}
Now I want to get the following highlighted ids of the user so how to fetch it. I am using scoped model as a state management in Flutter.
I did it with javascript so far but in the documentation it seems not taht different for flutter:
private void writeNewUser(String userId, String name, String email) {
User user = new User(name, email);
mDatabase.child("users").child(userId).setValue(user);
}
https://firebase.google.com/docs/database/android/read-and-write?authuser=0
This is the example shown in the docs. with .child('users') you can get the right section .child(userId) gives you access to the values.
All you have to do now is defining the variable userId
flutter
you can achieve this as follows
stream: FirebaseDatabase.instance
.reference()
.child('users')
.equalTo(userId)
.onValue,