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))
Related
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.
I followed the documentation on pub/sub notifications with the push method here
And I want to have authentication on my call with JWT. I looked at their GitHub example here
app.post('/pubsub/authenticated-push', jsonBodyParser, async (req, res) => {
// Verify that the request originates from the application.
if (req.query.token !== PUBSUB_VERIFICATION_TOKEN) {
res.status(400).send('Invalid request');
return;
}
// Verify that the push request originates from Cloud Pub/Sub.
try {
// Get the Cloud Pub/Sub-generated JWT in the "Authorization" header.
const bearer = req.header('Authorization');
const [, token] = bearer.match(/Bearer (.*)/);
tokens.push(token);
// Verify and decode the JWT.
// Note: For high volume push requests, it would save some network
// overhead if you verify the tokens offline by decoding them using
// Google's Public Cert; caching already seen tokens works best when
// a large volume of messages have prompted a single push server to
// handle them, in which case they would all share the same token for
// a limited time window.
const ticket = await authClient.verifyIdToken({
idToken: token,
audience: 'example.com',
});
const claim = ticket.getPayload();
claims.push(claim);
} catch (e) {
res.status(400).send('Invalid token');
return;
}
// The message is a unicode string encoded in base64.
const message = Buffer.from(req.body.message.data, 'base64').toString(
'utf-8'
);
messages.push(message);
res.status(200).send();
});
But I have some questions.
What is the PUBSUB_VERIFICATION_TOKEN and how do I get it and store it in my environment?
const [, token] = bearer?.match(/Bearer (.*)/); throws the following error
Type 'RegExpMatchArray | null | undefined' must have a 'Symbol.iterator' method that returns an iterator.ts(2488)
Why do they push the claims and tokens in an array if they never check that array in this function for already existing tokens / claims?
I am trying to implement this with a Firebase Cloud Function and this is what I have. Is it even possible to cache the tokens / claims?
//Service account auth client
const authClient = new google.auth.JWT({
email: android_key.client_email,
key: android_key.private_key,
scopes: ["https://www.googleapis.com/auth/androidpublisher"]
});
export const handlePubSub = functions.region('europe-west1').https.onRequest(async (req, res) => {
// What is PUBSUB_VERIFICATION_TOKEN???
if (req.query.token !== PUBSUB_VERIFICATION_TOKEN) {
res.status(400).send('Invalid request');
return;
}
try {
const bearer = req.header('Authorization');
const [, token] = bearer?.match(/Bearer (.*)/); //Error Type 'RegExpMatchArray | null | undefined' must have a 'Symbol.iterator' method that returns an iterator.ts(2488)
tokens.push(token); // Why do this? Can I do this in firebase cloud functions
const ticket = await authClient.verifyIdToken({
idToken: token,
});
const claim = ticket.getPayload();
claims.push(claim); // Why do this? Can I do this in firebase cloud functions
} catch (e) {
res.status(400).send('Invalid token');
return;
}
const message = Buffer.from(req.body.message.data, 'base64').toString(
'utf-8'
);
console.log(message);
return res.status(200).json({
statusCode: 200,
method: req.method,
message: 'Recieved successfully'
});
});
What is the PUBSUB_VERIFICATION_TOKEN and how do I get it and store it
in my environment?
PUBSUB_VERIFICATION_TOKEN can be any value you want. Easiest way to set an environment variable is on the command line when running node:
PUBSUB_VERIFICATION_TOKEN=whatevertoken node app.js
The req.query.token that is compared too comes from the URL query string.
GET /whatever?token=whatevertoken
Type 'RegExpMatchArray | null | undefined' must have a
'Symbol.iterator' method that returns an iterator.ts(2488)
That's a bug in their code. bearer.match can return undefined/null which can't be spread into the array [, token]. The example will only work when there is a successful regex match. This will parse in plain javascript but typescript highlights this issue at compile time.
const bearer = req.header('Authorization');
const m = /Bearer (.*)/.exec(bearer)
if (m) tokens.push(m[1])
Why do they push the claims and tokens in an array if they never check
that array in this function for already existing tokens / claims?
The example comments // List of all messages received by this instance.
So more a debug store than something functional.
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.
hello guys i developed an android app that http post req some data like latitude, longitude and IMEI to server that post in database. everything is working fine, but now comes the second part of the project. I need to make an web application that shows me on map a market with the lat and long saved in database and i don't understand how. I understood i should use querys but i don't understand who to use them.
this is my server side.
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var app = express();
//connect to mongodb:
/*mongoose.connect('mongodb+srv://tudorstanciulescu:19970826#test-
srqul.mongodb.net/test?retryWrites=true&w=majority', {useNewUrlParser:
true} );
*/
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/mydb";
//app.use(bodyParser.urlencoded({extended:true}));
//app.use(bodyParser.json());
app.use(bodyParser.json());
//var mongoose = require('mongoose');
app.post('/postBazaDate',(req,res)=> {
var latitudine = req.body.latitudine;
var longitudine = req.body.longitudine;
var imei = req.body.imei;
var dateTime = new Date();
;
var data = {
"latitude" : latitudine,
"longitute" : longitudine,
"imei" : imei,
"dateTime" : dateTime
}
// data.save()
// .then(item => {
// res.send("item saved to database");
// })
// .catch(err => {
// res.status(400).send("unable to save to database");
// });
MongoClient.connect(url, { useNewUrlParser: true }, function(err,
db) {
if (err) throw err;
var dbo = db.db("mydb");
dbo.collection("date_locatie").insertOne(data, function(err, res)
{
if (err) throw err;
console.log("1 document inserted");
});
});
i don't have any errors, everything is working fine, but i can't understand how to use the data from database in a script from an html
In Node.js, same place where you have added app.post
app.get('/getBazaDate',(req,res)=> {
MongoClient.connect(url, { useNewUrlParser: true }, function(err,
db) {
if (err) throw err;
var dbo = db.db("mydb");
dbo.collection("date_locatie").find({}, function(err, data)
{
if (err) throw err;
res.send(data); // here data is containing all saved data in array
//format
});
});
in html file
<!DOCTYPE html>
<html>
<body>
<h2>The = Operator</h2>
<p id="demo"></p>
<script>
const userAction = async () => {
fetch('http://localhost:3000/getBazaDate')
.then(response => response.json())
.then(json => console.log(json))
}
userAction();
document.getElementById("demo").innerHTML = response.json;
</script>
</body>
</html>
Simple REST Explanation
Ok so first is first, an html file is static and its contents can only be manipulated through javascript or css or someother language. Therefore, either you fetch the data before you load the page and send the data with the page , or you create an ajax call to get the data.
In a rest architecture you have GET , PUT , PATCH, POST ,DELETE Requests, each request is to either create ,read , or update the database.
A GET is to send data from server -> client, therefore a client requests data from the server and the server fetches and prepares the data for the client and sends it back.
Both PUT and PATCH updates the data in the database
A POST is to send from client -> server and save data
A DELETE to delete a row from the database
For more information about restfull you can visit this website: https://www.restapitutorial.com/lessons/httpmethods.html
or do a quick google search rest tutorial and you will find many !
Code Time
SERVER SIDE (USE ONE OF THESE) :
// app.js
// THIS GETS ONE ROW AND RETURNS OBJECT FROM THE DATABASE ACCORDING TO YOUR QUERY
app.get("/", (req,res,next) {
dbo.collection("date_locatie").find({}, function(err, res) {
if (err) throw err;
res.send(data);
});
})
// THIS GETS MANY ROWS AND RETURNS ARRAY FROM THE DATABASE ACCORDING TO YOUR QUERY
app.get("/", (req,res,next) {
dbo.collection("date_locatie").findAll({}, function(err, res) {
if (err) throw err;
res.send(data);
});
})
Now that your server is setup to get accept a GET REQUEST AND send back the data
All you have to do is call the url using an ajax call in javascript and your data will be sent to the client's pc.
To show the data you need to loop (if its array) and append data to HTML.
CLIENT SIDE :
In an html file you can write javascript in a script tag. This allows for the DOM elements to be manipulated. Supposed you have an empty with id locationData
and you want to fill it with the data that you saved
//index.html
//Assuming you are using jQuery
<div id="locationData"></div>
<script>
// WHEN HTML IS FULLY LOADED SENDS A GET REQUEST TO YOUR SERVER TO FETCH
// THE DATA
$( document ).ready(function() {
$.ajax({url: "http://localhost:3000/", success: function(result){
// PUTS THE DATA IN THE DIV WITH ID : locationData
$("#locationData").html(result);
}});
});
<script>
I need to authenticate via Android on my website (Zend Framework2+ZfcUser+ZfcUserDoctrineORM).
I want to call an url that authenticate me and return a json object that contains my session_id.
I don't know if it is the correct way but whatever i don't know how to do that with zfcUser.
David
Next, i will be able to store this session_id into Shared Preferences storage.
First of all sorry for my English.
In my application i need almost the same.
Ok. So in yoursite.com/module/YourModuleName/Module.php do:
use YourModuleName\Model\YourModuleName;
use YourModuleName\Model\YourModuleName;
class Module {
public function onBootstrap(MvcEvent $e) {
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$auth = $sm->get('zfcuser_auth_service');
$model = new OrdersManager();
if (!$auth->hasIdentity()) {
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($app, $sm, $auth, $model) {
$match = $e->getRouteMatch();
// No route, this is a 404
if (!$match instanceof RouteMatch) {
return;
}
$match = $e->getRouteMatch();
$matchParams = $match->getParams();
// $matchParams['hash'] == some url param
if (isset($matchParams['hash'])) {
$model->setDbAdapterColibo($sm->get('dbAdapter'));
$usersSqlObject = $model->getUsers();
$salt = md5('caw');
foreach ($usersSqlObject as $key => $user) {
$hash = hash('sha256', $salt.$param1.$user['user_id']);
if ($hash == $matchParams['hash']) {
$authAdapter = $sm->get('ZfcUser\Authentication\Adapter\AdapterChain');
$request = $app->getRequest();
$request->getPost()->set('identity', $user['email']);
// You may use user password to auth user
$request->getPost()->set('credential', $user['user_id']);
$result = $authAdapter->prepareForAuthentication($request);
$auth->authenticate($authAdapter);
// do your staff with session or other.
// after this you will be redirect to page from where query was
break;
}
}
}
});
}
}
}
Don`t forget about yoursite.com/module/YourModuleName/config/module.config.php
You need to add route with your URL param, to receive it in $matchParams = $match->getParams();
In case I have describe you will be auth and immediately redirect to the site.
Example:
http://example.com/someController/someAction/param1/param2/hash...
the result will be auth and open page http://example.com/someController/someAction/param1/param2/hash...
Ok. This is what i need for my app. Hope this help.
P.S. Some ideas get from Zend Framework 2 - Global check for authentication with ZFCUser