Google photos Authorisation Error Error 400: invalid_request - flutter

I'm trying to upload images to google photos or google drive I have followed the documentations and a lot of internet videos but it keeps send me the same error
my code is the same as this code literally but it doesn't work for me
https://github.com/JideGuru/youtube_videos/tree/master/google_photos_upload/lib
I used oAuth 2 I think the problem is in it I entered the SHA1 and SHA256 correctly from my device and it didn't worked then I tried pushing my project first at firebase then modify it in google cloud but it keep showing the same error here is the code to upload,
import 'dart:convert';
import 'dart:io';
import 'package:googleapis_auth/auth_io.dart';
import 'package:url_launcher/url_launcher.dart';
import 'constants.dart';
class PhotosService {
final List<String> _scopes = [
'https://www.googleapis.com/auth/photoslibrary'
];
Future<AuthClient> getHttpClient() async {
AuthClient authClient =
await clientViaUserConsent(ClientId(clientId), _scopes, _userPrompt).catchError((e) => print(e));
return authClient;
}
upload(File file) async {
AuthClient client = await getHttpClient();
var tokenResult = await client.post(
Uri.parse('https://photoslibrary.googleapis.com/v1/uploads'),
headers: {
'Content-type': 'application/octet-stream',
'X-Goog-Upload-Content-Type': 'image/png',
'X-Goog-Upload-Protocol': 'raw'
},
body: file.readAsBytesSync(),
);
print(tokenResult);
var res = await client.post(
Uri.parse(
'https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate'),
headers: {'Content-type':'application/json' },
body: jsonEncode({
"newMediaItems": [
{
"description": "item-description",
"simpleMediaItem": {
"fileName": "flutter-photos-upload",
"uploadToken": tokenResult.body,
}
}
]
}),
);
print(res.body);
}
_userPrompt(String url) {
print(url);
launch(url);
}
}
maybe google added new restrictions for authentication so if anyone knows what should I do I would be thankful

Related

api calls - Flutter

I'm trying to make a api call but I can't success, everything goes fine until the call, and there stop everything and the function finish, what I do wrong?
Future<String> get() async {
var url = Uri.parse("https://10.0.2.2:7021/api/Auth/login");
var headers = {"content-type": "application/json"};
final msg = jsonEncode(
{"username": "string", "password": "string", "email": "string"});
var response = await http!.post(url, body: msg, headers: headers);
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
print("Correct");
return "Correct";
} else {
print(response.statusCode);
print("User not allowed");
throw Exception("User not allowed");
}
}
Mistake comes here
debug window
You have probably imported the "wrong" http. Do it like that:
import 'package:http/http.dart' as http;
You dont need to write http! because http is a package and is never null and since you are doing http! I guess you imported something wrong in your code.
EDIT:
Maybe your device can't reach 10.0.2.2 (or that port), you should set a timeout to find it out fast:
http.post(url, body: msg, headers: headers).timeout(
const Duration(seconds: 3),
onTimeout: () {
// request timed out
return http.Response('Error', 408);
},
);
Have you imported http package like this?
import 'package:http/http.dart' as http;
And use case like this
var response = await http.post(url, body: msg, headers: headers);
add .php to login in the url :
https://10.0.2.2:7021/api/Auth/login.php
if you are working with php
or .py for python

Is there something wrong with the way [Flutter Web] sends a request POST message to the API server?

The open api request I'm trying to use requires an image binary value with content-type of multipart/form-data format.
I know you can't use dart:io in flutter web. I tried to upload an image in multipart/form-data format to the api server in flutter web while looking at several posts.
However, only a message appeared stating that the image could not be recognized.
This is the last thing I tried to create multipart types in flutter web.
import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
PlatformFile? objFile;
pickImage() async {
var result = await FilePicker.platform.pickFiles(
withReadStream: true,
);
setState(() {
objFile = result!.files.single;
});
uploadImage();
}
uploadImage() async {
FormData formData = FormData.fromMap({'image' : MultipartFile(test!, objFile!.size, filename: objFile!.name)});
Dio dio = new Dio();
var response = await dio.post('API url', data: formData);
}
I additionally used Multipart.form Bytes from http , Multipart.form Bytes from dio . But the result was the same.
The value checked by the request body through the postman interceptor.
content-type=multipart/form-data;bounary=--dio-boundary-1105759322
----dio-boundary-1105759322
content-disposition: form-data; name="image"; filename="test.jpeg"
content-type: application/octet-stream
ÿØÿÛC
%# , #&')*)-0-(0%()(ÿÛC
(((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀŽv"ÿÄÿÄC!1AQaq"‘2¡±#BÁÑR3CðñSbr’á‚Â$&4c“ÿÄÿÄ&!1A2Q"a3BRÿÚ?ù× „É<$/cŸt8D`aú¦Ä#bálŒZVM„ٔʓTL›eOò¢“
èKÇ(p¢‰¥C’ÄÙ‚Ñx²Ù1Jcœ)B›¢$ ¢‚&
‚7› ˜Žp”{&ÊÀÁAî¤Æ
‚nÈ CØÃêOýÒ›§á$sÊ‚r¡ìLÂ…;"éMI½î«gæV<æ6οÙ%_ƒY®}7Òû€¯MŒ&g¹å|µ£ëÐúc\tÚƵƈúÕ]#kQ‹D/Ÿú·cu9«Hà/¢lÚ–êè·¼&Þt
¯H‚&ɶìÛà®iƒh²SöãÔTs[l›/?[s(’˜¨o€¤Û‹*¥AÖ”ðbUgYR’!äJ!M‹™‹«›î©aÉ*ᕨ4p SÉ…¤)‰ì§=‘âJ» oÙGDRåÌy0—²û r ò€·²?Te8±KSTR8ŹDAååþ7)Oˆk)õ²Qk#Ù€Œ ?DÜû&Ä›„ÍÅ”lQjð¡NÑ%HTWP˜²wýÒc(Ÿð¤ð¢S<*6º>ÊaCœ „Ù0
^J(ª%¢ƒFPm‘^u4^èM‘åL…##•0Qÿ ºi…32§ÙC•D¿&Èw’ˆº‘Ü"…”<&ýРwP {p ¸DCd¼&ÿ©#¨ˆ› La~¨p¦„)’÷‚ˆº²æÒ›ªĘ̀Šaá€0‹n <ò¦M“YM„ L«=ÕnæÊlªŽÂƒóc„m‚—È™Uó ªºäªÛ•F†\…}7?¨ªZL`*£è¾ŽÝÌ1¤ÜBúk6­
---------------------------SKIP------------------------------
PTiMÂ!¢(èÊ€YÊÂœ"ÑÂ_T<Ñ5îPp™ð ¨„ôOˤ?¢z\ÂÚ¡½ÐiÊc쨟ÝHŸ¢“3ÝA˜( ‘ÊH›(l€Å¼)Ä‘rEÈ[€‹¬”¼x
W7q?ΣHt®“§¤y\½Ìÿ:ÿÍtÖ§T°AÊÕ\ËZVƒÔPha30%1*¶›Ž!7è¥|f›„îÕQ±„9N6åW,¨^Ù8PHN./Ê€îª2ß*{(l¡™šOU¢Ôå3œ*ꜨŠ‹“3¼$«B*ÌŒS„+EÒ‘Ý VHpV±`²³ó€µgܪ‚#“Ü)À!NPCƒÝIÅԛ–”xý”²™# ?U‚‹n€å!Œ¦&é*ƒ™¨wÄÖØY¢>«}&ü¢×\Ý?ó*9ç%Òº˜#çò H€¥&ꃒ¤(
‚0O8##EÎéÊœ#TÕr‚ºT¹ÈÔ7T“2¢ƒœbÅsuOî¶Ô0>‹ŸT|Gô•Óa®ïšÔÇe¤T
he<,¨[ü¶[…·M#ZOˆjtˤÝE© QÿÙ
----dio-boundary-1105759322--
When I use the MultipartFile.fromFile method used in flutter ios, I got the response normally. So I'm pretty sure there must be some mistake or misinformation in the flutter web setup.
Thanks in advance!
this is how I managed to upload an image to Laravel backend using Flutter Web
import 'dart:io';
import 'package:dio/dio.dart' as dio;
import 'package:file_picker/file_picker.dart';
Future pickupUserImage2() async {
PlatformFile? objFile;
var picked = await FilePicker.platform.pickFiles();
objFile = picked!.files.single;
String? apiUrl = Get.find<MainController>().apiUrl;
String url = '';
if (apiUrl != null) url = apiUrl + 'images';
List<int> list;
list = List<int>.from(objFile.bytes!);
dio.FormData formData = dio.FormData.fromMap({'file': dio.MultipartFile.fromBytes(list, filename: objFile.name)});
DioNetworking _dio = new DioNetworking();
dynamic result = await _dio.postData(
url,
formData,
contentType: 'multipart/form-data',
);
if (result['status'] == true) {
showToast(result['message']);
return ImageModel.Image.fromJson(result['data']);
}
}
I added a file using MultipartFile.fromBytes which has the first parameter as List which I created from this method "List.from(objFile.bytes!);"
Notes :
ImageModel.Image is a model I created to handle the image result
DioNetworking is a class that perform dio requests , I just created it to do the
authentication stuff
import 'package:dio/dio.dart';
class DioNetworking {
Dio _dio = new Dio();
Future postData(
String url,
dynamic data, {
String? contentType,
}) async {
try {
Response response = await _dio.post(url,
data: data,
options: Options(headers: {
'content-type': contentType != null ? contentType : 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer ${token ?? ''}'
// other headers
}));
if (response.statusCode == 200) {
dynamic data = response.data;
return data;
} else {
print(response.statusCode);
}
} on DioError catch (e) {
print(e);
if (e.type == DioErrorType.connectTimeout) {
return {'status': 'Connect Timed Out'};
}
if (e.type == DioErrorType.receiveTimeout) {
return {'status': 'Receive Timed Out'};
}
if (e.type == DioErrorType.response) {
print(e.response!.data);
print(e.response!.headers);
}
}
}
}

Flutter REST Calls Time Out

I am making api calls via flutter to my server. I have checked my android manifest settings and I have placed
<uses-permission android:name="android.permission.INTERNET"/>
But, the api calls time out. Here is my call:
Future driverLogin(userdetails) async {
var url = 'http://$_server/api/token/';
print(userdetails.values);
await http.post(url, body: json.encode(userdetails), headers: {
"Content-Type": "application/json"
}).then((http.Response response) {
print(response.body);
final Map<String, dynamic> responseData = json.decode(response.body);
Token tkn = Token.fromJSON(responseData);
_accessTkn = tkn.access;
_refreshTkn = tkn.refresh;
print('Refreshingly refreshed ${tkn.refresh}');
if (response.statusCode == 200) {
addToken(_accessTkn);
addRefresh(_refreshTkn);
print(responseData);
// tokenType = 'email';
print('Signed In');
// preformLogin();
} else {
// popupSwitch(2);
print('Error Could not sign in');
}
});
return _accessTkn;
}
When I run it I get this error:
Bad state: Insecure HTTP is not allowed by platform:
make sure to import like this.
import 'package:http/http.dart' as http;
and make your url like this.
var url = 'https://$_server/api/token/';
Also check this links maybe will help you
https://flutter.dev/docs/release/breaking-changes/network-policy-ios-android
https://medium.com/flutter-community/solving-the-new-https-requirements-in-flutter-7abe240fbf23

Upload Image/File to Strapi (Flutter Web)

I'm trying to upload an image to Strapi through Flutter Web. I'm aware (from this link) that I need to use FormData to do so. I've researched on many ways to do this and I stumble across Dio and of course Http.
Both solutions gave me errors:
Unsupported operation: MultipartFile is only supported where dart:io is available.
I've tried this code:
var request = new http.MultipartRequest("POST", Uri.parse(url));
request.files.add(
await http.MultipartFile.fromPath(
"files",
imageFilePath,
),
);
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
print(response.statusCode);
}).catchError((e) => print(e));
As suggested here.
And many other getting errors or Empty Data (400), when I use MultipartFile.fromBytes(...).
I'm just trying to upload a file, therefore I assume my body should only contain the FormData with as files as it's mentioned on Strapi's Documentation.
So, I searched on the Flutter Discord for some help and I found out that my problem happens because Flutter Web can't use 'dart:io' , and using 'dart:html' takes away the use of all of Flutter's platforms.
I ended up using this imports:
import 'dart:convert';
import 'dart:typed_data';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:path/path.dart';
import 'package:async/async.dart';
and this is the function I created and worked:
Future<bool> uploadImage(
String imageFilePath,
Uint8List imageBytes,
) async {
String url = SERVERURL + "/uploadRoute";
PickedFile imageFile = PickedFile(imageFilePath);
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var uri = Uri.parse(url);
int length = imageBytes.length;
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('files', stream, length,
filename: basename(imageFile.path),
contentType: MediaType('image', 'png'));
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
I had this issue using Strapi and this solution worked like a charm.
Upload file during entry creation with Flutter
dio: ^3.0.10, mime: ^1.0.0 and http_parser.
The main part is the key name of the file if it's foo, so you have to change files.image with files.foo for file upload
final mimeType = mime.lookupMimeType(imageFile.path, headerBytes: [0xFF, 0xD8])?.split('/');
FormData formData = new FormData.fromMap(
{
"files.image": await MultipartFile.fromFile(
imageFile.path,
filename: imageFile.path.split('/').last,
contentType: MediaType(mimeType?[0], mimeType?[1]),
),
"data": jsonEncode({
"title": title,
"summary": summary,
"content": content,
}),
},
);
Response response = await _dio.post(
"/blogs",
data: formData,
options: Options(),
);
In Flutter Web:
I am using node.js with express as backend source I have created the following simple method to upload image and text data to localhost server using xamp
String url = 'http://localhost:8080/blog_upload';
var request = http.MultipartRequest('POST', Uri.parse(url));
imagebytes = await image.readAsBytes();
List<int> listData = imagebytes!.cast();
request.files.add(http.MultipartFile.fromBytes('field_name', listData ,
filename:'myFile.jpg'));
request.fields['name'] = 'Mehran Ullah Khan';
request.fields['country'] = 'Pakistan';
var response = await request.send();
I have used the following dependencies in the above method.
http: ^0.13.3
image_picker: ^0.8.2
how we used the image_picker?
first globally declare image and imagebytes
image = await ImagePicker().pickImage(source: ImageSource.gallery);
And this is the method in the backend I have used.
app.post('/blog_upload', upload.single('field_name'), async (req, res, next) => {
let data = {name_db: req.body['name'], Country_db:req.body['country'],};
let sqlq = `INSERT INTO TableName SET ? `;
db.query(sqlq, data, (insertionErr, insertionResult) => {
if (insertionErr) {
console.log('failed_upload');
throw insertionErr;
}
else {
console.log('done_upload');
res.send(insertionResult);
}
});
});
In the above method I have used
multer and express packages
You can see full details for multer and express in this link
#Diego Cattarinich Clavel
String url = Constants.BASE_URL + HttpUrls.categories;
PickedFile imageFile = PickedFile(path);
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var uri = Uri.parse(url);
int length = imageBytes.length;
var request = new http.MultipartRequest(
"PUT",
uri,
);
var multipartFile = new http.MultipartFile(
'files.categoryImage',
stream,
length,
filename: basename(imageFile.path),
contentType: MediaType('image', 'png'),
);
request.files.add(multipartFile);
request.fields['data'] = '{"category":$category}';
print(request.url);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});

How to connect api in laravel of flutter apps?

How can I connect my flutter apps with laravel api? Below is what I post in postman.
http://10.0.2.2/voyce/api/register
I try to run the API in postman and it does not give any response.
here is my api.dart in flutter.
api.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
class CallApi{
final String _url = 'http://10.0.2.2/voyce/api/';
postData(data, apiUrl) async {
var fullUrl = _url + apiUrl + await _getToken();
return await http.post(
fullUrl,
body: jsonEncode(data),
headers: _setHeaders()
);
}
getData(apiUrl) async {
var fullUrl = _url + apiUrl + await _getToken();
return await http.get(
fullUrl,
headers: _setHeaders()
);
}
_setHeaders() => {
'Content-type' : 'application/json',
'Accept' : 'application/json',
};
_getToken() async {
SharedPreferences localStorage = await
SharedPreferences.getInstance();
var token = localStorage.getString('token');
return '?token=$token';
}
}
All I want it to make the api able to connect? I think maybe there is something wrong with my laravel API but I dont have any idea where to fix it.
If you've encounter the error SocketException: OS Error: Connection refused, this is most likely a network connection error. When trying to post the url in the browser and you get the proper response, then the problem could be in the postman. But you can refer here for more details on how to integrate Laravel in Flutter.