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,
Related
i want to store token value and navigate home page using go router after login. i dont know how to handle json data like display or (retrieve)name and role.. i am newbie for programming.
Help me.thanks in advance.i tried futurebuilder examples it not worked. kindly give simple solution.
Future<Loginuser> fetchLoginuser(String mobile, String password) async {
final response = await http.post(
Uri.parse('https://random.url/api/login'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(
<String, String>{'mobile': mobile, 'password': password}));
if (response.statusCode == 200) {
return Loginuser.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to update album.');
}
}
class Userinfo {
double branchcode;
double role;
double name;
Userinfo({required this.branchcode, required this.role, required this.name});
factory Userinfo.fromJson(Map<String, dynamic> json) {
return Userinfo(
branchcode: json['branchcode'], role: json['role'], name: json['name']);
}
}
class Loginuser {
final String message;
final String messagecode;
final String token;
final Userinfo userinfo;
const Loginuser({
required this.message,
required this.messagecode,
required this.token,
required this.userinfo,
});
factory Loginuser.fromJson(Map<String, dynamic> json) {
return Loginuser(
message: json['message'],
messagecode: json['messagecode'],
token: json['token'],
userinfo: json['userinfo']);
}
}
Use shared_preferences usage is straight forward
here just do this
if (response.statusCode == 200) {
Loginuser _user = Loginuser.fromJson(json.decode(response.body));
final prefs = await SharedPreferences.getInstance();
await prefs.setString('token', user.token);
return user;
} else {
throw Exception('Failed to update album.');
}
And next time you want to check wether user was logged in or not
final prefs = await SharedPreferences.getInstance();
final String? action = prefs.getString('token');
if(token == null){ //not logged in}else{ //logged navigate to dashboard}
///Create a separate helper/manager for shared preferences. This is just an example///
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());
}
I have a page from which I need to save data locally as a list. To save, I use SharedPrefs, there, through the model, I save the data as a list. But I ran into a problem that I can not specify the format for receiving data List, tell me how can I save data as a list and receive data as a list?
class RecentlySearchedModel {
String name;
String address;
RecentlySearchedModel({
required this.name,
required this.address,
});
factory RecentlySearchedModel.fromJson(Map<String, dynamic> json) {
return RecentlySearchedModel(
name: json['name'] as String,
address: json['address'] as String,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'address': address,
};
}
}
repository
#override
Future setResentlySearched({required List<RecentlySearchedModel> searchedList}) async {
final SharedPrefs prefs = SharedPrefs();
await prefs.setString(_name, jsonEncode( ))
}
#override
Future<List<RecentlySearchedModel>?> getResentlySearched() async {
final SharedPrefs prefs = SharedPrefs();
final data = await prefs.getString(_name);
if (data == null) return null;
return List<RecentlySearchedModel>.fromJson(
jsonDecode(data),
);
}
update your repository like this.
#override
Future setResentlySearched({required List<RecentlySearchedModel> searchedList}) async {
final SharedPrefs prefs = SharedPrefs();
await prefs.setString(_name, jsonEncode(searchedList.toJson());
}
#override
Future<List<RecentlySearchedModel>?> getResentlySearched() async {
final SharedPrefs prefs = SharedPrefs();
final data = await prefs.getString(_name);
if (data == null) return null;
Iterable l = json.decode(data);
List<RecentlySearchedModel> posts = List<RecentlySearchedModel>.from(l.map((model)=> RecentlySearchedModel.fromJson(model)));
return posts;
}
i havent try to complie, but its should be like this
Future setResentlySearched({required List<RecentlySearchedModel> searchedList}) async {
List<Map<String,dynamic>> listItem = searchedList.map((e)=> e.toJson()).toList();
String jsonString = jsonEncode(listItem);
final SharedPrefs prefs = SharedPrefs();
await prefs.setString(_name, jsonString)
}
and get it back
Future<List<RecentlySearchedModel>?> getResentlySearched() async {
final SharedPrefs prefs = SharedPrefs();
final data = await prefs.getString(_name);
if (data == null) return null;
return (jsonDecode(data) as List).map((e)=> RecentlySearchedModel.fromJson(e)).toList();
}
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);
}
I am trying to save the list dragged from the sql to be saved in SharedPreferences, I tried using this code:
static Future<List<User>> getUsers() async {
final myUserId = await getUser();
try {
var myUser = myUserId;
var map = Map<String, dynamic>();
map['user'] = myUser;
final response = await http.post(ROOT, body: map);
//print('getUsers Response: ${response.body}');
//print(myUser);
if (200 == response.statusCode) {
List<User> listContacts = parseResponse(response.body);
SharedPreferences contacts = await SharedPreferences.getInstance();
contacts.setStringList('contacts', listContacts);
return listContacts;
} else {
return List<User>();
}
} catch (e) {
return List<User>(); // return an empty list on exception/error
}
}
the User class for the list is the following:
class User {
final String firstName;
final String lastName;
final String imageLink;
User({this.firstName, this.lastName, this.imageLink});
factory User.fromJson(Map<String, dynamic> json) {
return User(
firstName: json['firstName'] as String,
lastName: json['lastName'] as String,
imageLink: json['imageLink'] as String,
);
}
}
So basically the data is successfully pulling it out from the database, and it does display it, but I want to save the data to SharedPreferences so it doesn't have to load every single time. The error that is occurring is that the listContacts can't be assigned to setStringList, since it is a List<User> and not a List<String>, but I don't know how else can I change the code in order to be able to set the SharedPreferences.
Here you can do is
static Future<List<User>> getUsers() async {
final myUserId = await getUser();
try {
var myUser = myUserId;
var map = Map<String, dynamic>();
map['user'] = myUser;
final response = await http.post(ROOT, body: map);
//print('getUsers Response: ${response.body}');
//print(myUser);
if (200 == response.statusCode) {
List<User> listContacts = parseResponse(response.body);
SharedPreferences contacts = await SharedPreferences.getInstance();
contacts.setString('contacts',json.encode(response.body)); //Here saved the response
return listContacts;
} else {
return List<User>();
}
} catch (e) {
return List<User>(); // return an empty list on exception/error
}
}
Now to fetch it I can use is
SharedPreferences contacts = await SharedPreferences.getInstance();
var response = json.decode(contacts.getString('contacts'));
List<User> listContacts = parseResponse(response.body);
and you get back your data from shared preferences