The argument type 'Set<String>' can't be assigned to the parameter type 'Map<String, String>' - flutter

I'm trying to create an user authentication system using Auth0 in my Flutter app. The Auth0 REST documentation gave an example of cURL but I didn't find any flutter package which does the job of cURL. So, I used http.
Here's the code:
Future<String> getToken(String userId) async {
final response = await http.post(
Uri.parse('https://my-auth0-subdomain.auth0.com/oauth/token'), // I used my real subdomain
body: jsonEncode({
'grant_type=client_credentials',
'client_id=my_project_client_id', // I used my real client id
'client_secret=my_project_client_secret', // I used my real client secret
'audience=https://my-auth0-subdomain.auth0.com/api/v2/' // I used my real subdomain
}),
headers: {
'content-type: application/x-www-form-urlencoded'
},
);
final token = jsonDecode(response.body)["access_token"];
return token;
}
This gives me an error that The argument type 'Set<String>' can't be assigned to the parameter type 'Map<String, String>'. on line 10 (headers: {...}). I can resolve this error by using headers: {'content-type': 'application/x-www-form-urlencoded'},.
But this then gives the error from Auth0 {"error":"access_denied","error_description":"Unauthorized"}. The API is set up properly, because on running
curl --request POST \
--url 'https://my-auth0-subdomain.auth0.com/oauth/token' \
--header "content-type: application/x-www-form-urlencoded" \
--data grant_type=client_credentials \
--data 'client_id=my_project_client_id' \
--data client_secret=my_project_client_secret \
--data 'audience=https://my-auth0-subdomain.auth0.com/api/v2/'
it returns a "access_token", "scope", "expires_in" and "token_type".
Please help. It's very important.
Thanks in advance :)

Try to send data as url encoded using :
Map<String, String> myBody= {
'grant_type' : 'client_credentials',
'client_id' : 'my_project_client_id', // I used my real client id
'client_secret' : 'my_project_client_secret', // I used my real client secret
'audience ' : 'https://my-auth0-subdomain.auth0.com/api/v2/' // I used my real subdomain
};
Future<String> getToken(String userId) async {
final response = await http.post(
Uri.parse('https://my-auth0-subdomain.auth0.com/oauth/token'), // I used my real subdomain
body: myBody,
headers: {
'content-type: application/x-www-form-urlencoded'
},
);
final token = jsonDecode(response.body)["access_token"];
return token;
}

Related

How do I do an graphql axios call to supabase to

I try to do an axios call to graphql in the documentation i see:
curl -X POST https://<PROJECT_REF>.supabase.co/graphql/v1 \
-H 'apiKey: <API_KEY>'\
-H 'Content-Type: application/json' \
--data-raw '
{
"query":"{ accountCollection(first: 3) { edges { node { id } } } }"
}'
I am transforming that to a axios call like that:
var callObject = {
url:https://<PROJECT_REF>.supabase.co/graphql/v1,
method:"POST",
headers:{
"Authorization" : "Bearer " + apiKey,
"apikey": apiKey,
"Content-Type": "application/json"
}
}
var response = await axios(callObject)
Now I tried many things to add the --data-raw payload into the call. But i couldn't find the solution. It always shows me a 404
How can handle that?

Flutter receives 422 response from Fastapi when posting a PNG file

I have created a working localhost API with FastAPI. The POST takes a PNG, does some image processing and returns a PNG as expected when I click the 'try it out' button in the FastAPI generated docs:
The curl post command shows as follows:
curl -X 'POST' \
'http://localhost:8345/api/predict' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'file=#test_img.png;type=image/png'
The image File is successfully retrieved from the image picker library. (Where the image1 object has been initialized as File image1; in the app page's class.
Future getImage() async {
var imageTmp = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
image1 = imageTmp;
print('Image Path $image1');
});
}
I tried to emulate the API call with the below function in Flutter.
doUpload() {
/*
curl -X 'POST' \
'http://192.168.178.26:8345/api/predict' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'file=#test_img.png;type=image/png'
*/
var request = http.MultipartRequest(
'POST',
Uri.parse("http://<my locally hosted ip>:8345/api/predict"),
);
Map<String, String> headers = {"Content-type": "multipart/form-data"};
request.files.add(
http.MultipartFile(
'image',
image1.readAsBytes().asStream(),
image1.lengthSync(),
filename: 'filename',
contentType: MediaType('image', 'png'),
),
);
request.headers.addAll(headers);
print("request: " + request.toString());
request.send().then((value) => print(value.statusCode));
}
When I run the doUpload() function, a POST is successfully sent to the localhost API, but it returns a 422 error 'unprocessable entity'.
What I tried:
I tried to set the image type in doUpload to jpg, jpeg, but I keep getting a 422 error.
I tried looking up where the image_picker is supposed to store the temporary file to see if it's stored correctly, but when I look at the generated filepath, I don't see the actual file and tmp folder:
filepath: File: '/data/user/0/<my package name>/cache/image_picker3300408791299772729jpg'
looking at my local UI filepath, I see:
It shows no folder named cache, so I can't inspect it like this. However, the image picker saves it with a jpg at the end (not .jpg, is this normal?)
I also tried adding this debugger function to my fastAPI server.py, but I'm not sure how I can inspect the resulting data in the current flutter code:
https://fastapi.tiangolo.com/tutorial/handling-errors/#use-the-requestvalidationerror-body
The resulting value has properties like statusCode and reason, but I don't see a full json output option.
To mimic that curl command exactly, use this: (I've used the convenience constructor for simplicity)
final request = http.MultipartRequest(
'POST',
Uri.parse('http://<my locally hosted ip>:8345/api/predict'),
);
request.files.add(
await http.MultipartFile.fromPath(
'file', // NOTE - this value must match the 'file=' at the start of -F
image1.path,
contentType: MediaType('image', 'png'),
),
);
final response = await http.Response.fromStream(await request.send());
print(response.body);

Flutter: MultipartRequest returns 403 Forbidden... CURL works fine

I try the following CURL command:
-X PUT \
-H 'Content-Type: application/octet-stream' \
--upload-file ${file_name} \
${url}
To upload a file into Google Storage (https://storage.googleapis.com/...?signature=...&...). This works just fine.
However, when I try to do it using the following Flutter code - I get a response with Error 403 (Forbidden):
Future<http.Response?> uploadVideo(
{required String uploadURL, required filePath}) async {
try {
ByteData bytes = await rootBundle.load(filePath);
var data =
http.MultipartFile.fromBytes('file', bytes.buffer.asInt64List());
Uri uri = Uri.parse(uploadURL);
var request = http.MultipartRequest(
'PUT',
uri,
);
request.files.add(data);
request.headers.addAll({
HttpHeaders.contentTypeHeader: 'Content-Type: application/octet-stream',
});
http.StreamedResponse response = await request.send();
return await http.Response.fromStream(response);
} on SocketException catch (e) {
showNoInternetError(e);
}
Any idea why this happens? The uploadURL is the same as the one I sent through CURL (very long string, with signature and ampersand signs etc).
Thanks a lot!!! <3

Getting 301 with Flutter OAuth

It's sad to see no concrete examples are available when it comes to using OAuth2 package of Flutter.
I'm a beginner, the example mentioned here is tough for me to crack(I learn mostly through videos), but my job requires me to implement OAuth by today itself. So I'm trying my shot here.
This is what I've:
Login API
curl --location --request POST 'https://domain/api/rest/oauth/token' \
--header 'Authorization: Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=<username_here>' \
--data-urlencode 'password=<md5_of_password_here'
I've been given a sample username and password as well..
This is what I've implemented so far..
void checkAuthentication() async {
String username = 'username';
String password = 'password';
String basicAuth =
'Basic ' + base64Encode(utf8.encode('$username:$password'));
print(basicAuth);
var body = jsonEncode(
<String, dynamic>{
'grant_type': 'password',
'username': 'username',
'password': 'password',
},
);
Response r = await http.post(
Uri.https('domain', 'api/rest/oauth/token'),
headers: <String, String>{
'authorization': basicAuth,
'Content-Type': 'application/x-www-form-urlencoded',
'accept': 'application/json',
},
body: body,
);
print(r.statusCode);
print(r.headers);
print(r.body);
}
I'm getting 301 as result..
What can I do to get 200. Please guide me.

How to put raw data in a http get request in Flutter(Dart)?

I'm trying to execute the following curl in dart but I can't find a way to achieve that:
curl --location --request GET 'https://someurl.com/query' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer xxxx' \
--data-raw '{
"query":"test_value",
"size":10
}'
The only way I've found to achieve this is to use POST and put the raw data inside the body but I was wondering if there is a real way to achieve that since the POST request with a body seems to be about 220ms slower than the GET one(I know that they should be almost equal, it may be something from the server when recieving the request).
The default get() method of the http package doesn't allow you to add data since that isn't a common thing to do. You can get around this by using the Request object directly for more fine-grained control, as stated in the docs:
Request req = Request('GET', Uri.parse('https://someurl.com/query'))
..body = json.encode(data)
..headers.addAll({
"Content-type": "application/json",
"Authorization": "Bearer xxxx"
});
var response await req.send();
if (response.statusCode == 200) {
// do something with valid response
}
I'd look at getting the POST variant working properly, since a GET method semantically shouldn't do anything with the provided body. But that's a different discussion of course.
import 'package:http/http.dart' as http;
// Define the raw data to be sent in the request
String rawData = '{ "key": "value" }';
// Send the GET request with the raw data as the body
http.Response response = await http.get(
'https://example.com/endpoint',
headers: {'Content-Type': 'application/json'},
body: rawData,
);
// Check the status code of the response to see if the request was successful
if (response.statusCode == 200) {
// The request was successful, process the response
} else {
// The request was not successful, handle the error
}