Why my flutter app http post request only work in localhost - android

I'm making an app that has a login function. It calls an HTTP POST request to API on my localhost to check the validity of the username and password and if it matches the data on PhpMyAdmin then it will route to the member page.
However, I want to change the await http.post from localhost XAMPP link to a public API link on my hosting. But it throws some errors whenever I do it and when I click on login button nothing happened. Here's the code:
class _MyHomePageState extends State<MyHomePage> {
TextEditingController user = new TextEditingController();
TextEditingController pass = new TextEditingController();
String msg = '';
Future<List> _login() async {
final response =
await http.post("http://tunnamacbook.local/login.php", body: {
"username": user.text,
"password": pass.text,
});
var datauser = json.decode(response.body);
if (datauser.length == 0) {
setState(() {
msg = "Đăng nhập thất bại";
});
} else {
if (datauser[0]['level'] == 'admin') {
Navigator.pushReplacementNamed(context, '/AdminPage');
} else if (datauser[0]['level'] == 'member') {
Navigator.pushReplacementNamed(context, '/MemberPage');
}
setState(() {
username2 = datauser[0]['name'];
});
}
return datauser;
}
...there's more but it's unnecessary to show here...
Here's the errors:
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: FormatException: Unexpected end of input (at character 1)
^
#0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1405:5)
#1 _ChunkedJsonParser.close (dart:convert-patch/convert_patch.dart:523:7)
#2 _parseJson (dart:convert-patch/convert_patch.dart:41:10)
#3 JsonDecoder.convert (dart:convert/json.dart:506:36)
The errors are the blue lines below:

I figured it out. It was the problem with the CORS Policy. Setting a CORS allow header in every http API call fixed it. For those who want an example code for this problem, search on Google for CORS allow header for Flutter http call. Since I switched my mobile app programming framework to React Native for better support and a larger Stackoverflow community so I can't write code for this problem in Flutter anymore.

Related

Flutter HEALTH package get steps from user returns always null?

I am working on a personal project and I am using flutter to develop an app (cross platform) that reads in the user's health data from google fit (Android) or Apple Health. I am using this package and even the EXACT same code like in the documentation (I am currently only testing on Android):
Future fetchStepData() async {
int? steps;
// get steps for today (i.e., since midnight)
final now = DateTime.now();
final midnight = DateTime(now.year, now.month, now.day);
bool requested = await health.requestAuthorization([HealthDataType.STEPS]);
if (requested) {
try {
steps = await health.getTotalStepsInInterval(midnight, now);
} catch (error) {
print("Caught exception in getTotalStepsInInterval: $error");
}
print('Total number of steps: $steps');
setState(() {
_nofSteps = (steps == null) ? 0 : steps;
_state = (steps == null) ? AppState.NO_DATA : AppState.STEPS_READY;
});
} else {
print("Authorization not granted - error in authorization");
setState(() => _state = AppState.DATA_NOT_FETCHED);
}
}
Then I am calling this function with await and I also have inserted the correct permission in all Android Manifest files:
Also I set up an OAuth2 Client ID for the project and added my google account as a test user.
BUT THE FUNCTION SETS THE VARIABLE STEPS ALWAYS TO NULL? The boolean variable "requested" is true, so it seems like the actual connection is working?
I am really disappointed by myself guys and I really need help - THANK YOU!
I tried adding the correct android permissions, asking for permissions explicitly, different time intervalls but nothing worked for me, I always got a null value back.

Apple Sign In Not Working in Flutter Android App

I have almost tried all the solutions present on github and stack overflow and double checked my code and procedure while integrating this sign in feature for my flutter android app but nothing works so far. I have also tried the dummy glitch server which is present mentioned in their document in this link, but this thing doesn't work for android as well whenever I tried to sign in using my apple id this plugin doesn't redirects back to my flutter app but stucks on this error after signing in successfully. Here is my code which I am using for signing in:
Future appleLogin() async {
var prefs = await SharedPreferences.getInstance();
try {
final rawNonce = generatingAEncryptionKey();
final nonce = generatingSHA256Key(rawNonce);
final appleUser = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: WebAuthenticationOptions(
// TODO: Set the `clientId` and `redirectUri` arguments to the values you entered in the Apple Developer portal during the setup
clientId: 'com.digidots.full-match',
redirectUri: Uri.parse('https://locrian-tin-polka.glitch.me/callbacks/sign_in_with_apple'),
),
nonce: nonce,
);
print("dataOf apple:-=-=-=-=- $appleUser");
var payload = {
'email': appleUser.email,
'name': appleUser.givenName,
'provider_id': appleUser.identityToken,
'devicetype': Platform.isIOS ? 'ios' : 'android',
'devicetoken': prefs.getString('device_token'),
};
flushBar('Please wait...');
socialLogin(payload);
} catch (error) {
print(error);
}
}
String generatingAEncryptionKey([int length = 32]) {
final charset =
'0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
final random = Random.secure();
return List.generate(length, (_) => charset[random.nextInt(charset.length)])
.join();
}
/// Returns the sha256 hash of [input] in hex notation.
String generatingSHA256Key(String input) {
final bytes = utf8.encode(input);
final digest = sha256.convert(bytes);
return digest.toString();
}
And here are screenshots of my error
The code above redirects my app to the apple signing in link
After signing in successfully it requests my permission to share the information
After pressing continue button it redirects me to link:
intent://callback?code=c4f89bed93fa0476982c1d17549ac3231.0.rrzrr.q3kBNYdzaM6lO84iXNmEfQ&id_token=eyJraWQiOiJlWGF1bm1MIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLmRpZ2lkb3RzLmZ1bGwtbWF0Y2giLCJleHAiOjE2MTUxMTc3NjEsImlhdCI6MTYxNTAzMTM2MSwic3ViIjoiMDAxOTExLjhkNDBiYWRmZjJkZDRjYWI4ODc3ZmJjYjY5YmNiNDQ5LjA4NDIiLCJub25jZSI6IjMyNjM5OWJmNGQ2NjVhMDc3MWY1ZjI3MzVmOTVmMDNhMzk2NDYwODVkMTViZDY2MmY0ZGFjZjNhNzlkMjAyNzAiLCJjX2hhc2giOiJubWcyMmdBMEpBZjJYRVBXRmNUVVNnIiwiZW1haWwiOiJoYW16YWJpbGFsZ2F5YUBob3RtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjoidHJ1ZSIsImF1dGhfdGltZSI6MTYxNTAzMTM2MSwibm9uY2Vfc3VwcG9ydGVkIjp0cnVlfQ.Smbuymx1Kk5oPXdRDnYWtJiqN7K6PLjyOsRaBgePg7H-_eWcO4F9bVi1UhTOaPK4HZ8fSk2PJ5hVBCyCsj0BhxJDMpn6Ne3MYnOZKHdWV6THYfKgnYLT7FDCePlpYZnZG9dhrhaK9HVw6Rvcfx0kEyNlNG6GZbAhb9DgfeZeGOIpdPMP0fjYmm8tdjqjRbBg-1VrRuV2wnyt0pzhrU8qvHsJVJHHCqO2WaN5lMXAMPCQJu1mZflL8HD0WnNOX8Lve-rEf4VEIRLVACRvSes6Qgkl5Lbnd2GKCk838Xk-N_VpgYCU7-Lmgn0HsSMFNuy1UI1I7xpr-b2cYD8ReHiO0w#Intent;package=com.digidots.full_match_app;scheme=signinwithapple;end
However it's main purpose is to redirect me back to my app again but it doesn't and the link results in below error

How to get Instagram Following List using Instagram graph api

How to get the following list from the Instagram account using the access token
I tried everything but not work.
here some API link which I tried before but none of them work.
I tried this one https://www.instagram.com/urvish_._/?__a=1
also this one
I tried but nothing can help me.
You can get the following (or also follower) list using the code below. Steps:
Make sure you're logged in on instagram.com
Open the API link: https://www.instagram.com/urvish_._/?__a=1 (your target username here is urvish_._)
Open the browser console: normally Ctrl+Shift+J on Windows/Linux or ⌘+Option+J on Mac
Paste this code and press Enter:
const GRAPHQL_MAX_PER_PAGE = 50;
async function getList() {
let pageLimit = 200; // from my testing
let baseInfo = JSON.parse(document.getElementsByTagName('body')[0].innerText);
let userId = baseInfo.graphql.user.id;
let config = { user_edge: 'edge_follow', query_hash: 'd04b0a864b4b54837c0d870b0e77e076', total_count: baseInfo.graphql.user.edge_follow.count };
// for followers instead of followings:
// { user_edge: 'edge_followed_by', query_hash: 'c76146de99bb02f6415203be841dd25a', total_count: baseInfo.graphql.user.edge_followed_by.count }
let after = null, hasNext = true, thisList = [];
for (pageCount = 1; hasNext && (pageCount <= pageLimit); ++pageCount) {
try {
let response = await fetch(`https://www.instagram.com/graphql/query/?query_hash=${config.query_hash}&variables=` + encodeURIComponent(JSON.stringify({
id: userId, include_reel: true, fetch_mutual: true, first: GRAPHQL_MAX_PER_PAGE, after: after
})));
if (!response.ok) {
console.warn(`Failed at page number ${pageCount.toLocaleString()}. HTTP status ${response.status}: ${response.statusText}.`);
break;
}
try {
response = await response.json();
} catch (error) {
console.error(`You may need to verify your account. Stopping. Failed at page number ${pageCount.toLocaleString()}.`, error);
break;
}
hasNext = response.data.user[config.user_edge].page_info.has_next_page
after = response.data.user[config.user_edge].page_info.end_cursor
thisList = thisList.concat(response.data.user[config.user_edge].edges.map(({ node }) => {
return {
id: node.id,
username: node.username,
full_name: node.full_name,
profile_pic_url: node.profile_pic_url,
};
}));
} catch (error) {
console.warn(`Error at page number ${pageCount.toLocaleString()}:`, error);
}
console.log(`${thisList.length.toLocaleString()} of ${config.total_count.toLocaleString()} fetched so far`);
}
console.info(`${thisList.length.toLocaleString()} fetched.`);
console.log(thisList);
}
getList()
Browser console showing a fetched list after code execution
In the code I've set the page limit to 200 so you can get up to 10,000 of your followings.
PS: For a way to visualise your lists and get more details, you can try Instagram Lists, a tool I made.

Android Firestore Stripe - Add Payment Source

Update At Bottom
I am trying to build a signup page in my Android app that signs users up for a subscription through Stripe. What I am stuck on is adding a payment source from Android, through a cloud function, and receive a token from Stripe.
I currently have solved, automatically adding a newly created User to Stripe. As well creating the subscription when (/users/{userId}/membership/token) is written to, or changed.
On Android I am able to obtain the credit card data through the input..
PaymentMethodCreateParams.Card card = cardInputWidget.getPaymentMethodCard();
I next need to submit this to my cloud function by using..
mFunctions = FirebaseFunctions.getInstance();
mFunctions.getHttpsCallable("addPaymentSource")
.call()
.addOnCompleteListener(task -> {
...
Being I am having trouble finding information on this, here is all I have for this cloud function (Javascript)
exports.addPaymentSource = functions.https.onCall((data, context) =>{
const pm = await stripe.paymentMethods.attach('pm_678', {customer: 'cus_123'});
return admin.firestore().collection('users').doc(user.uid).get('membership').set({token: token});
}
I need to obtain the customer number which is saved at - /users/{user.uid}/customerId'. As well pass the payment method through my http data call, and pass/obtain the user_id (which would have been created long before all this).
I got this far watching this youtube video and converting my code over. Subscription Payments with Stripe, Angular, and Firebase
I also referenced Stripe's Cloud Function examples quite a bit. The one issue is everyone seems to be using this code (below), which doesn't work in my implementation. With most guides/examples not being used for Subscriptions.
// Add a payment source (card) for a user by writing a stripe payment source token to Cloud Firestore
exports.addPaymentSource = functions.firestore.document('/stripe_customers/{userId}/tokens/{pushId}').onCreate(async (snap, context) => {
const source = snap.data();
const token = source.token;
if (source === null){
return null;
}
try {
const snapshot = await admin.firestore().collection('stripe_customers').doc(context.params.userId).get();
const customer = snapshot.data().customer_id;
const response = await stripe.customers.createSource(customer, {source: token});
return admin.firestore().collection('stripe_customers').doc(context.params.userId).collection("sources").doc(response.fingerprint).set(response, {merge: true});
} catch (error) {
await snap.ref.set({'error':userFacingMessage(error)},{merge:true});
return reportError(error, {user: context.params.userId});
}
});
Update:
Made some small changes to get try and get this to work..
exports.addPaymentSource = functions.https.onCall((data, context) =>{
///users/{userId}/membership/token
// Create Payment Method
const paymentMethod = stripe.paymentMethods.create(
{
type: 'card',
card: {
number: '4242424242424242',
exp_month: 5,
exp_year: 2021,
cvc: '314',
},
}).then(pm => {
console.log('paymentMethod: ', paymentMethod.id);
return stripe.paymentMethods.attach(paymentMethod.id, { customer: 'cus_HCQNxmI5CSlIV5' })
.then(pm => {
return admin.firestore().collection('users').doc(user.uid).get('membership').set({token: pm.id});
});
});
});
I am getting close, the problem is paymentMethod.id is 'undefined'
While I'm not a Firebase expert, on your Android side, you want to call your cloud function with parameters of the Customer ID and PaymentMethod ID in order to pass them to your cloud function.
Passing parameters shown here: https://stackoverflow.com/a/56298213/10654456
Then in your cloud function, you want to attach the PaymentMethod to the Customer (as you are doing using stripe-node) and make it the Customer's default for Subscriptions, as shown here: https://stripe.com/docs/billing/subscriptions/payment#signup-3
Then, you should create a Subscription on the Customer for a particular Plan, again using stripe-node, as shown here https://stripe.com/docs/billing/subscriptions/payment#signup-4
Here I have my functioning code. (I used some placeholder data to fill in the variables)
exports.addPaymentSource = functions.https.onCall((data, context) =>{
// Create Payment Method
stripe.paymentMethods.create( {
type: 'card',
card: {
number: '4242424242424242',
exp_month: 5,
exp_year: 2021,
cvc: '314',
},
})
.then(pm => {
return stripe.paymentMethods.attach(pm.id, { customer: 'cus_HCCNMAAwRhNM3c' })
})
.then(pm => {
console.log('final step');
console.log('paymentMethod: ', pm.id);
admin.firestore().collection('users').doc('LzgbQBtk0QSZi7QISIbV').set({token: pm.id});
return admin.firestore().collection('users').doc(user.uid).collection('membership').set({token: pm.id});
})
.catch(error => { return null });
});
So I manually pasted in some variables to confirm my features were functioning. The CustomerID and card details need to be passed in from the Android app. These card details are the only ones I should need for a subscription
'pm' is the returned Payment Method object, in which id is the variable that needs to be attached to the user.
Finally pm.id is the token that must be saved inside into the firestore. Doing this triggers my subscription setup cloud function(not displayed).
The code displayed shows how to avoid nested then statements, and Android firestore direct function calling. While also not shown, the data field can call upon any variable's key word "data.cardnbr".
The method avoids any use of SetupIntents. While this is incredibly effective for Subscription based charging, it might not be best practice for direct charges.

Flutter "Mailer" API Multiple Image Attachments

I'm making a simple app for getting personal information from the user and number of images to send them through backend mail API with a one click of a button. So far, I can get and send the FormData through mail but I couldn't figure it out the how to send an array of images.
I have tried several API's but "Mailer" seems to best for SMTP. As for the code, I tried to convert the "File" class to String or List but none of those have worked for me. I'am not a intermediate coder so be kind with me :)
That's how I get the images using "image_picker"
File _image1;
Future getImage1Camera() async {
var image1 = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image1 = image1;
});
}
And the "mailer" code
void _mailer() async{
if(!_formKey.currentState.validate()){
return;
}else{
_formKey.currentState.save();
}
String gmailUsername = '**';
String gmailPassword = '**';
final smtpServer = gmail(gmailUsername, gmailPassword);
final ceSendMail = Message()
..from = Address(gmailUsername, '')
..recipients.add('recipent')
..subject = 'Test'
..text = 'Plain Text'
..html = ''//Form Data
..attachments.add(_image1);//TODO: User input images
try {
final sendReport = await send(cekSendMail, smtpServer);
print('Message sent: ' + sendReport.toString());
} on MailerException catch (e) {
print('Message not sent.');
for (var p in e.problems) {
print('Problem: ${p.code}: ${p.msg}');
}
}
// Create a smtp client that will persist the connection
var connection = PersistentConnection(smtpServer);
// Send the message
await connection.send(cekSendMail);
// close the connection
await connection.close();
}
This is the error I get and whatever I try it's always the "type" error.
The argument type 'File' can't be assigned to the parameter type 'Attachment'.
So, how can I get multiple image files from user and send through mail API?
You need to wrap your file with FileAttachment
..attachments.add(FileAttachment(_image1))

Categories

Resources