While creating user getting user as null - flutter

(Flutter) User is always getting null and unable to create user in realtime database
Future validateform() async {
FormState? formState = _formKey.currentState;
if(formState!.validate()) {
formState.reset();
User? user = firebaseAuth.currentUser;
// String? useruid = user!.uid;
print(user);
if(user == null ) {
print(_emailTextController.text);
print(_nameTextController.text);
print('UserID: '+'{$user}');
print(gender);
firebaseAuth
.createUserWithEmailAndPassword(
email: _emailTextController.text,
password: _passwordTextController.text)
.then((user) => {
_userServices.createUser(
{
"username": _nameTextController.text,
"email": _emailTextController.text,
// "userId": useruid,
"userId": user.user!.uid,
// "userId": "5as564d65as4d65as4d65as4d64",
"gender": gender,
})
}).catchError((err) => {print(err.toString())});
// });
print(user);
if (user!=null) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
}
}
}
}
I was expecting it to creaete in REALTIME DATABASE as user details, but user is always null.

Related

Flutter - Firebase - Delete a document without having access to it

I am trying to have access to notificationId once it gets created however the delete function deletes all the documents under this collection ('user-notifications').
Do you know what I need to change so I can remove only one document rather than all documents in this collection?
Future<String> likeAnnouncementNotification(String announcementId,
String imageUrl, String ownerUid, String uid, List liked) async {
String notificationid = const Uuid().v1();
String res = "Some error occurred";
try {
if (liked.contains(uid)) {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.where("uid", isEqualTo: FirebaseAuth.instance.currentUser?.uid)
.get()
.then((value) {
value.docs.forEach((document) {
document.reference.delete();
});
});
} else {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.doc(notificationid)
.set(
{
'imageUrl': imageUrl,
'announcementId': announcementId,
'notificationid': notificationid,
'timestamp': DateTime.now(),
'type': 0,
'uid': uid
},
);
}
res = 'success';
} catch (err) {
res = err.toString();
}
return res;
}
the only thing i see that you need to specify what notification document you went to delete add it like parameter when you call likeAnnouncementNotification function
Future<String> likeAnnouncementNotification(
String announcementId,
String imageUrl,
String ownerUid,
String uid,
List liked,
) async {
String notificationid = const Uuid().v1();
String res = "Some error occurred";
try {
if (liked.contains(uid)) {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.where("uid", isEqualTo: FirebaseAuth.instance.currentUser?.uid)
.get()
.then((value) {
value.docs.forEach((notification) {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.doc(notification.id) // this is the problem you need to specify what notification document you went to delete.
.delete();
});
});
} else {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.doc(notificationid)
.set(
{
'imageUrl': imageUrl,
'announcementId': announcementId,
'notificationid': notificationid,
'timestamp': DateTime.now(),
'type': 0,
'uid': uid
},
);
}
res = 'success';
} catch (err) {
res = err.toString();
}
return res;
}

Unable to store data in cloud firestore

I am unable to store data in cloud firestore. Authentication is all correct but the data is not going in cloud firestore and because of that login also not working because cloud firestore is pre-req to login function
That's my AuthContoller function
storeUserData({name, password, email}) async {
DocumentReference store = firestore
.collection("users")
.doc(FirebaseAuth.instance.currentUser!.uid);
store.set(
{'name': name, 'password': password, 'email': email, 'imageUrl': ''});
}
and that's my signup button code
try {
await controller
.signupMethod(
context: context,
email: emailController.text,
password: passwordController.text,
)
.then((value) {
** return controller
.storeUserData(
email: emailController.text,
name: nameController.text,
password: passwordController.text)
.then((value) {
VxToast.show(context,
msg: 'Account Created Sucessfully');
Get.offAll(LoginScreen());
}); **
});
} catch (e) {
FirebaseAuth.instance.signOut();
VxToast.show(context, msg: e.toString());
}
try this
storeUserData({name, password, email}) async {
final _firestore = FirebaseFirestore.instance;
await _firestore.collection("users")
.doc(FirebaseAuth.instance.currentUser!.uid).set(
{'name': name, 'password': password, 'email': email, 'imageUrl': ''});
}

No object exists at the desired reference

I am trying to get an image from the storage and use the url for a default profile picture but i am getting this error.
firebase_storage/object-not-found No object exists at the desired reference.
This is my code.
void authenticateStudent() async {
User? currentStudent;
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
await firebaseAuth
.createUserWithEmailAndPassword(
email: umailController.text.trim(),
password: passwordController.text.trim(),
)
.then((auth) {
currentStudent = auth.user;
}).catchError((onError) {
print(onError);
});
if (currentStudent != null) {
FirebaseStorage.instance
.ref()
.child('profile')
.getDownloadURL()
.then((url) {
imageUrl = url;
});
saveDataToFirestore(currentStudent!).then((value) {
Navigator.pop(context);
print("User added successfully");
});
}
}
Future saveDataToFirestore(User currentStudent) async {
FirebaseFirestore.instance
.collection("students")
.doc(currentStudent.uid)
.set({
"studentUID": currentStudent.uid,
"fname": fnameController.text.trim(),
"lname": lnameController.text.trim(),
"Mobile": phoneController.text.trim(),
"Program": selectedProgram,
"student_id": studentidController.text.trim(),
"cohort": selectedCohort,
"umail": currentStudent.email,
"profilepicture": imageUrl,
"active": active,
"status": status
});
}
The database is structured like this
This is my code.
void authenticateStudent() async {
User? currentStudent;
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
await firebaseAuth
.createUserWithEmailAndPassword(
email: umailController.text.trim(),
password: passwordController.text.trim(),
)
.then((auth) {
currentStudent = auth.user;
}).catchError((onError) {
print(onError);
});
if (currentStudent != null) {
FirebaseStorage.instance
.ref()
.child('profile')
.getDownloadURL()
.then((url) {
imageUrl = url;
});
saveDataToFirestore(currentStudent!).then((value) {
Navigator.pop(context);
print("User added successfully");
});
}
}
Future saveDataToFirestore(User currentStudent) async {
FirebaseFirestore.instance
.collection("students")
.doc(currentStudent.uid)
.set({
"studentUID": currentStudent.uid,
"fname": fnameController.text.trim(),
"lname": lnameController.text.trim(),
"Mobile": phoneController.text.trim(),
"Program": selectedProgram,
"student_id": studentidController.text.trim(),
"cohort": selectedCohort,
"umail": currentStudent.email,
"profilepicture": imageUrl,
"active": active,
"status": status
});
}
The database is structured like this
Your code says:
FirebaseStorage.instance
.ref()
.child('profile')
.getDownloadURL()
But in the screenshot, the file is called profile.png. The path must match completely and exactly, so:
FirebaseStorage.instance
.ref()
.child('profile.png')
.getDownloadURL()

The client_secret Provided does not match any associated PaymentIntent on this account

I'm trying to use flutter_stripe for a stripe connect account, But I always get the
same error: The client_secret provided doesn't match the client_secret associated with the PaymentIntend.
I've completed all steps according to flutter_stripe but I still face this error.
Below is my code Please check this and help me.
inde.js
const functions = require("firebase-functions");
const stripe = require("stripe")("secret_key");
exports.stripePaymentIntentRequest = functions.https.onRequest(async (req, res) => {
try {
let customerId;
//Gets the customer who's email id matches the one sent by the client
const customerList = await stripe.customers.list({
email: req.body.email,
limit: 1
});
//Checks the if the customer exists, if not creates a new customer
if (customerList.data.length !== 0) {
customerId = customerList.data[0].id;
}
else {
const customer = await stripe.customers.create({
email: req.body.email
});
customerId = customer.data.id;
}
//Creates a temporary secret key linked with the customer
const ephemeralKey = await stripe.ephemeralKeys.create(
{ customer: customerId },
{ apiVersion: '2020-08-27' }
);
//Creates a new payment intent with amount passed in from the client
const paymentIntent = await stripe.paymentIntents.create({
amount: parseInt(req.body.amount),
currency: 'usd',
customer: customerId,
})
res.status(200).send({
clientSecret: paymentIntent.client_secret,
paymentIntent: paymentIntent,
ephemeralKey: ephemeralKey.secret,
customer: customerId,
success: true,
})
} catch (error) {
res.status(404).send({ success: false, error: error.message })
}
});
PaymentService.dart
Future<void> initPaymentSheet(
{required BuildContext context, required String email, required int amount}) async {
try {
// 1. create payment intent on the server
final response = await http.post(
Uri.parse(
'Firebase api link of Functions'),
body: {
'email': email,
'amount': amount.toString(),
});
Map<String, dynamic> paymentIntentBody = jsonDecode(response.body);
log(paymentIntentBody.toString());
//2. initialize the payment sheet
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: paymentIntentBody["clientSecret"],
merchantDisplayName: 'Flutter Stripe Store Demo',
customerId: paymentIntentBody['customer'],
customerEphemeralKeySecret: paymentIntentBody['ephemeralKey'],
style: ThemeMode.light,
testEnv: true,
merchantCountryCode: 'US',
),
);
await Stripe.instance.presentPaymentSheet();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Payment completed!')),
);
} catch (e) {
if (e is StripeException) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error from Stripe: ${e.error.localizedMessage}'),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error the Stripe of : $e')),
);
}
}
}
The log error print on my console is :
> [log] {paymentIntent:
> pi_3LI2acCTAUDjRNFV1Ra3dahz_secret_Fcqw73pWrE4avKRyuDVzRBitG,
> ephemeralKey:
> ek_test_YWNjdF8xSlQ3amtDVEFVRGpSTkZWLDl1OE5Vdm1jTGY4T1RpaVhHOTB3NTRVSkQ5UGl4azA_00j32OYG9n,
> customer: cus_LHG2YpQP9Cgwuy, success: true}
The following code is from a previous Stripe evaluation stage. But it worked. Slim it down to your needs.
Remember to publish your secret key to the server, so the server can talk to Stripe.
code.dart
Future<bool> payWithPaymentSheet(
ProductModel productModel, PriceModel priceModel,
{String merchantCountryCode = 'DE'}) async {
if (kIsWeb) {
throw 'Implementation not availabe on Flutter-WEB!';
}
String uid = AuthService.instance.currentUser().uid;
String email = AuthService.instance.currentUser().email ?? '';
HttpsCallableResult response;
try {
response = await FirebaseFunctions
.httpsCallable('createPaymentIntent')
.call(<String, dynamic>{
'amount': priceModel.unitAmount,
'currency': priceModel.currency,
'receipt_email': email,
'metadata': {
'product_id': productModel.id,
'user_id': uid,
"valid_until": productModel.getUntilDateTime().toIso8601String(),
'product_name': productModel.name.tr,
},
'testEnv': kDebugMode,
});
} on FirebaseFunctionsException catch (error) {
log(error.code);
log(error.details);
log(error.message ?? '(no message)');
Get.snackbar(
error.code,
error.message ?? '(no message)',
icon: const Icon(Icons.error_outline),
);
return false;
}
Map<String, dynamic> paymentIntentBody = response.data;
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: paymentIntentBody["clientSecret"],
currencyCode: priceModel.currency,
applePay: false,
googlePay: false,
merchantCountryCode: merchantCountryCode,
merchantDisplayName: Strings.appName,
testEnv: kDebugMode,
customerId: paymentIntentBody['customer'],
customerEphemeralKeySecret: paymentIntentBody['ephemeralKey'],
));
try {
await Stripe.instance.presentPaymentSheet();
return true;
} on StripeException catch (e) {
log(e.error.code.name);
log(e.error.message ?? '(no message)');
log(e.error.localizedMessage ?? '(no message)');
Get.snackbar(e.error.code.name, e.error.message ?? '',
icon: const Icon(Icons.error_outline));
} catch (e) {
Get.snackbar('An unforseen error occured', e.toString(),
icon: const Icon(Icons.error_outline));
}
return false;
}
index.ts
// SETTING SECRET KEY ON SERVER:
// cd functions
// firebase functions:config:set stripe.secret_key="sk_live_51L...Noe"
// firebase deploy --only functions
let stripe = require("stripe")(functions.config().stripe.secret_key);
exports.createPaymentIntent = functions
.https.onCall((data, context) => {
// if (!context.auth) {
// return { "access": false };
// }
return new Promise(function (resolve, reject) {
stripe.paymentIntents.create({
amount: data.amount,
currency: data.currency,
receipt_email: decodeURIComponent(data.receipt_email),
metadata: data.metadata,
}, function (err, paymentIntent) {
if (err != null) {
functions.logger.error("Error paymentIntent: ", err);
reject(err);
}
else {
resolve({
clientSecret: paymentIntent.client_secret,
paymentIntentData: paymentIntent,
});
}
});
});
});

Flutter | How to store login response in SQFlite database

Here I am doing login when I am logged in successfully it will store all the info in SQFLite database.
here is my login response where I don't know how to store string array and JSON in flutter SQFlite. I need to store all this response info in SQFLite.
Can anyone helps me to create a table based on this response?
{
"loginUser": {
"token": "eyJhbGciOiZTMzLTQ4NmItYmFhNS0wODRhMWI2Nzg3YjQiJhY2Nlc3MifQ.bLKz-y9W6VKXRXkG6fbxlrmcowRNupKL0g",
"user": {
"aclRoleId": [
"cmr",
"bsp"
],
"confirmationSentAt": "2019-12-30T09:12:08Z",
"confirmationToken": "$argon2id$v=19$m=131072,t=8,p=4$WQoFfhBUfabw7g1BgNuuxg$BmUEYNWTZHeCnY0xCqOT+nWEDNlXcrNIEWQZkA51oCk",
"confirmedAt": null,
"country": {
"capital": "New Delhi",
"code": "IND",
"contactInfo": null,
"currencyCode": "INR",
"currencySymbol": "₹",
"id": "3",
"isdCode": "+91",
"name": "India",
"officialName": "The Republic of India"
},
"currentSignInAt": null,
"email": "john#mailinator.com",
"failedAttempts": null,
"id": "1",
"language": {
"code": "EN",
"id": "1",
"isActive": true,
"name": "English"
},
"lockedAt": null,
"meta": null,
"mobile": "(999)-000-0040",
"profile": {
"first_name": "John",
"last_name": "Doe"
},
"resetPasswordSentAt": null,
"resetPasswordToken": null,
"scopes": null,
"signInCount": 12,
"statusId": "confirmed",
"token": null,
"unlockToken": null
}
}
}
Here is a one way of doing it:
import 'dart:io';
import 'package:path/path.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:utility_demos/user_management/user.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
DatabaseHelper.internal();
// create database
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "main.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
// create tables
void _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE User(uid INTEGER AUTO INCREMENT PRIMARY KEY, token TEXT, user TEXT)");
// note that Im inserting password as plain text. When you implement please store it as a hash for security purposes.
}
// insert user to db when login
Future<int> saveUser(User user) async {
Database dbClient = await db;
int res = await dbClient.insert("User", user.toMap());
return res;
}
// retrieve user from db
Future<User> getUser() async {
var dbClient = await db;
List<Map> list = await dbClient.rawQuery('SELECT * FROM User');
if (list.isNotEmpty) {
return User.fromJson(list.elementAt(0));
}
return null;
}
//delete use when logout
Future<int> deleteUser() async {
var dbClient = await db;
int res = await dbClient.delete("User");
return res;
}
// check if the user logged in when app launch or any other place
Future<bool> isLoggedIn() async {
var dbClient = await db;
var res = await dbClient.query("User");
return res.length > 0 ? true : false;
}
}
Here is the User model class:
class User {
final String user;
final String token;
User(this.user, this.token);
// here because of user object is too long Im storing it as string
// and that is actually not a good way to do this because of when you want to
// fetch user and handle information it will be very hard to do those and also when testing
// please map other properties in your json to model and that's the best way.
User.fromJson(dynamic obj)
: this.user = obj['user'].toString(),
this.token = obj['token'];
String get getUser => user;
String get getToken => token;
Map<String, dynamic> toMap() => {'user': user, 'token': token};
}
Here I have created a simple widget tree to show you. How to store retrieved json object properties. Please note that I'm storing json user object as String because of its pretty long. Its better to create your model for all variables and map them. See comment in User class.
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:utility_demos/user_management/database_helper.dart';
import 'package:utility_demos/user_management/user.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter SO answers sample snippet',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future<bool> doLogin() async {
String data = await DefaultAssetBundle.of(context).loadString("assets/login_mock_data.json");
final decoded = json.decode(data);
try {
if (decoded != null) {
final user = User.fromJson(decoded["loginUser"]);
DatabaseHelper dbHelper = new DatabaseHelper();
await dbHelper.saveUser(user);
return true;
}
} catch (e) {
debugPrint(e.toString());
}
return false;
}
// just to show you how to fetch from db
Future<String> getLoggedInUser() async {
bool isLoggedIn = await doLogin();
if (isLoggedIn) {
User user = await DatabaseHelper().getUser();
return user.getToken;
}
return null;
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getLoggedInUser(),// this is also not a good practice :D, since each and every time build method execute this will invoke too.
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Center(child: Text("Something..."));
} else if (snapshot.hasData) {
// just to show you how to fetch from db
if (snapshot.data != null) {
return Center(child: Text("Logged in token: ${snapshot.data}"));
}
return Center(child: Text("Not logged in"));
}
return Center(child: CircularProgressIndicator());
},
);
}
}