I want to redirect user on details payment screen when payment is initiated and change state automatically when user confirm payment.
Detail screen :
child: FutureBuilder<Deposit?>(
future: AuthService.addDeposit(amount, product, phone, authProvider.token!),
builder: (BuildContext context, AsyncSnapshot<Deposit?> snapshot){
if(snapshot.hasData){
return _snapshotHasData(snapshot.data!);
}else if(snapshot.hasError){
return Text('${snapshot.error}');
}
return const LinearProgressIndicator();
},
)
Service:
static Future<Deposit?> addDeposit(String amount, String product, String phone, String token) async {
assert(token.isNotEmpty);
Response<String> response = await _dio.post(
'url',
data: <String, String>{
'amount': amount,
'product': product,
'phone': phone,
},
);
if(response.statusCode != 200){
throw Exception(response.statusMessage);
}
return Deposit.fromJson(jsonDecode(response.data ?? ''));
}
I put just one parameter for show you the widget
Widget _snapshotHasData(Deposit data){
return Text(data.amount);
}
Related
I'm attempting to delete a Firebase user account that has data in several other collections. Because Firebase requires a recent login in order to delete accounts or change passwords, I'm asking the user to sign in again in the following code. The code below deletes the user account, but the application automatically shuts after pressing the delete button. Lost connection to the device. The user is still signed in with their data when I restart the app (perhaps because it is persistent), so I have to manually log them out.
The code is as follows-
This Function runs when delete account button is pressed.
/// Function to delete user account
void deleteUserAccountEmail(
{required String password, required BuildContext context}) async {
//
try {
await _auth
.signInWithEmailAndPassword(
email: currentUser!.email!, password: password)
.then(
(_) async {
//
currentUser = _auth.currentUser;
//
_rankController.deleteRank();
// Deleting user
currentUser!.delete().then(
(value) => signOut(),
);
},
);
} catch (error) {
final e = error.toString().replaceRange(0, 14, '').split(']')[1];
_uniWidgets.errorSnackBarFN(
errorTitle: 'Error',
errorMessage: e,
);
}
}
StreamBuilder in the HomeScreen Body
return StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
return _authController.currentUser!.emailVerified
? HomeScreen()
: AuthScreen();
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
return AuthScreen();
}
},
);
} else {
return NoConnectionScreen();
}
Service:
static Future addDeposit(String amount, String product, String phone, String token) async {
assert(token.isNotEmpty);
try{
Response<String> response = await _dio.post(
'url',
data: <String, String>{
'amount': amount,
'product': product,
'phone': phone,
},
);
if (response.statusCode == 200){
return Deposit.fromJson(jsonDecode(response.data ?? '{}'));
}else if(response.statusCode == 400){
return Deposit.fromJson(response.data ?? '');
}else{
throw Exception(response.statusMessage);
}
}catch (e){
print(e);
}
}
child: FutureBuilder<Deposit?>(
future: AuthService.addDeposit(amount, product, phone,),
builder: (BuildContext context, AsyncSnapshot<Deposit?> snapshot){
if(snapshot.hasData){
return _snapshotHasData(snapshot.data!);
}else if(snapshot.hasError){
return Text('${snapshot.error}');
}
return const LinearProgressIndicator();
},
),
Error: The argument type 'Future' can't be assigned to the parameter type 'Future<Deposit?>?'.
'Future' is from 'dart:async'.
'Deposit' is from 'package:ias/models/deposit_model.dart' ('lib/models/deposit_model.dart').
future: AuthService.addDeposit(amount, product, phone),
Try to add data return type
Future<Deposit?> addDeposit(String amount, String product, String phone, String token) async {
More about null-safety
I have created a group screen in my flutter app and when I hit the create button it create a group as described is code:
//Create group
Future<String> createGroup(String groupName1, userUid) async {
String retVal = "error";
List<String> members = [];
try {
members.add(userUid);
DocumentReference docRef;
docRef = await firestore.collection("groups").add({
'name': groupName1,
'leader': userUid,
'members': members,
'groupCreate': Timestamp.now(),
});
retVal = "success";
} catch (e) {
// ignore: avoid_print
print(e);
}
return retVal;
}
I am stuck in getting the snapshot from my FBbackend. I want to get the info and display is on my group screen. How can I achieve that?
I have try to get the snapshot but it says Text("..."). I think the problem is that the value of DocumentReference? docRef; is empty, but I don’t know how to fixed it.
code:
DocumentReference? docRef;
docRef == null
? const Text('Error No Group Name Found!!')
: // 👈 handle null here
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection('groups')
.doc(docRef!.id)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return const ErrorScreen();
}
return Center(
child: Text((snapshot.data
as DocumentSnapshot<
Map<String, dynamic>>)['name']),
);
}),
This is my service function that communicate with the database
Future<News?> getNewsList(String token) async {
var url = Uri.tryParse('${baseUrl}get-news-list');
var response =
await http.post(url!, headers: {'Authorization': 'Bearer $token'});
if (response.statusCode == 200) {
var map = json.decode(response.body);
var list = News.fromJson(map);
print("map:${list.data![0]}");
return News.fromJson(map);
} else {
return News(message: null, status: false, data: null);
}
}
This my viewModel class I am using mvvm pattern
class NewsViewModel extends ChangeNotifier {
ApiOp api = ApiOp();
Future<List<NewsModel?>?> getNews() async {
String token ="token-here";
var map = await api.getNewsList(token);
List<NewsModel?>? list = map!.data;
print("object:${list![0]!.title}");
notifyListeners();
return list;
}
}
And here where I show the data on the view
Consumer<NewsViewModel?>(
builder: (context, value, child) => FutureBuilder<dynamic>(
future: value!.getNews(),
builder: (context, snapshot) {
List? list = snapshot.data;
print("list:$list");
return ListView.builder(
itemCount: 2,
itemBuilder: (context, index) {
return FirsatWidget(
title:"",
date: "",
photoUrl: "lib/assets/temp/4.jpg",
);
},
);
}),
),
But when I run the app some print function spamming in the debug like these prints
print("object:${list![0]!.title}");
print("map:${list.data![0]}");
Is this code continuously send post to the server or just rebuilding the consumer
Is this code continuously send post to the server or just rebuilding
the consumer
You are continuosly sending http reqests to your server.
You don't need to use Consumer<NewsViewModel?> and notifyListeners(); because you are using FutureBuilder which gets data from that future.
Try this code:
FutureBuilder<dynamic>(
future: Provider.of<NewsViewModel>(context,listen:false).getNews(),
builder: (context, snapshot) {
List? list = snapshot.data;
print("list:$list");
return ListView.builder(
itemCount: 2,
itemBuilder: (context, index) {
return FirsatWidget(
title:"",
date: "",
photoUrl: "lib/assets/temp/4.jpg",
);
},
);
}),
),
And comment notifyListeners()
class NewsViewModel extends ChangeNotifier {
ApiOp api = ApiOp();
Future<List<NewsModel?>?> getNews() async {
String token ="token-here";
var map = await api.getNewsList(token);
List<NewsModel?>? list = map!.data;
print("object:${list![0]!.title}");
// notifyListeners();
return list;
Let me know if you have issues and still have rebuilds.
I try to display a custom message when user logs or when log fail.
My post api call returns nothing, so I wanted to base on response status code to know if log went well or not.
I did something like in my api :
Future<Response> login(String email, String password) async {
final http.Response response = await http.post(
baseUrl + 'auth/login',
headers: headers,
body: jsonEncode(<String, dynamic> {
'email': email,
'password': password
}),
);
return response.statusCode == 200 ? Response(statusCode: 200) : Response(message: "Failed to login");}
class Response {
final String message;
final int statusCode;
Response({this.message, this.statusCode});
factory Response.fromJson(Map<String, dynamic> json) {
return Response(
message: json["message"],
);}}
And I call this method inside a FutureBuilder to display the message:
FutureBuilder(
future: lap.login(emailController.text, passwordController.text),
builder: (BuildContext context, AsyncSnapshot<Response> snapshot) {
if(snapshot.hasData)
print(snapshot.data.statusCode);
return CircularProgressIndicator();
},);
In my print method, I print nothing I don't understand why it doesn't display status code I return in my api method.
Could someone know why ?
Well I finally did the job with a .then().
Still don't understand why the first way didn't do it but after all, it works.
onPressed: () {
if(_formKey.currentState.validate()) {
lap.login(emailController.text, passwordController.text)
.then((responseMessage) => Scaffold
.of(context)
.showSnackBar(SnackBar(content: Text(responseMessage.message))));
}
},