Google Firebase HTTP Post - java

I'm trying to request POST for Google Firebase in server. I followed the document guideline, but it has not worked.
My sending message function is following thing.
private static void sendMsg() throws IOException
{
String url = "https://fcm.googleapis.com/fcm/send";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Authorization", "key=XXXX");
JSONObject msg=new JSONObject();
msg.put("message","test8");
JSONObject parent=new JSONObject();
parent.put("to", "XXXXX");
parent.put("data", msg);
con.setDoOutput(true);
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + parent.toString());
System.out.println("Response Code : " + responseCode+" "+con.getResponseMessage());
}
The response code is "411" and the message is "Length Required".
I also tried to set the content length, but the result was same.
Am I doing wrong?

You have all the setup right but are not writing the data. Add the statements shown:
con.setDoOutput(true);
// Added
OutputStreamWriter os = new OutputStreamWriter(con.getOutputStream());
os.write(parent.toString());
os.flush();
os.close();

Related

PATCH Request in Java using MSAL (msal-client-credential-secret)

I'm using client credential secret to run API on Microsoft Endpoint (Intune).
Example used from link.
Getting access token. (Working)
Get android Managed App Protections. (Working using GET HTTP Method)
Patch Request. (Not Working)
The examples do not mention any PATCH or POST request, hence need some help for it.
I tried the below code snippet but it fails.
private void setAndroidModels(final String accessToken, final String policyId, final String modelList)
throws IOException {
URL url = new URL(
"https://graph.microsoft.com/beta/deviceAppManagement/androidManagedAppProtections/" + policyId);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("PATCH");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = modelList.getBytes();
os.write(input, 0, input.length);
}
int httpResponseCode = conn.getResponseCode();
System.out.println("POST Response Code : " + httpResponseCode);
System.out.println("POST Response Message : " + conn.getResponseMessage());
}
Result : Exception in thread "main" java.net.ProtocolException: Invalid HTTP method: PATCH
Also tried
private void setAndroidModels(final String accessToken, final String policyId, final String modelList)
throws IOException {
URL url = new URL(
"https://graph.microsoft.com/beta/deviceAppManagement/androidManagedAppProtections/" + policyId);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("X-HTTP-Method-Override", "PATCH");
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = modelList.getBytes();
os.write(input, 0, input.length);
}
int httpResponseCode = conn.getResponseCode();
System.out.println("POST Response Code : " + httpResponseCode);
System.out.println("POST Response Message : " + conn.getResponseMessage());
}
Result :
POST Response Code : 400
POST Response Message: Bad Request
How can I get the client credential secret logic working for POST and PATCH HTTP Methods?
We can directly call patch request in MS Graph.
When creating PATCH requests to the API, you need to create a new
PATCH object that contains only the information you want to update.
This should be distinct from any objects you receive from the service
from a GET or a POST.
Please refer Document for more details.
For example, Patch rquest to user
User realMe = graphClient.me().buildRequest().get();
User patchMe = new User();
patchMe.givenName = "Beth";
realMe = graphClient
.users(realMe.userPrincipalName)
.buildRequest()
.patch(patchMe);

Java USES HTTP v1 to send Chinese notifications that are error characters

The request header is the same as the official document. Why did android receive the wrong character when I used Chinese? Using English is correct
private HttpURLConnection getConnections() throws IOException {
URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessTokens());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;
}

Microsoft Graph 401 Unauthorized with access token

Unable to get data from the the Microsoft Graph API.
private String getUserNamesFromGraph() throws Exception {
String bearerToken = "Bearer "+getAccessToken();
String url = "https://graph.microsoft.com/v1.0/users";
String returnData = null;
try {
URL apiURL = new URL(url);
URLConnection con = apiURL.openConnection();
con.setRequestProperty("Authorization", bearerToken);
con.setRequestProperty("Content-Type", "application/json");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
returnData = response.toString();
System.out.println(returnData);
} catch(Exception e) {
System.out.println(e);
}
return returnData;
}
private String getAccessToken() throws Exception {
String url = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
// header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "eTarget API");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
String urlParameters = "client_id=***
APPLICATION ID FROM APPLICATION REGISTRATION PORTAL ***&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=***
APPLICATION SECRET FROM APPLICATION REGISTRATION PORTAL ***&grant_type=client_credentials";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
String returnData = response.toString();
System.out.println(returnData);
Map jsonTokenData = new Gson().fromJson(returnData, Map.class);
String accessToken = (String)jsonTokenData.get("access_token");
//System.out.println(accessToken);
return accessToken;
}
The application is registered
I have a method getAccessToken() that successfully returns an access token
The method getUserNamesFromGraph() however returns a 401 Unauthorized instead of the expected data.
I've gone through the documentation countless times, trying different variations and endpoints but to no avail. Any ideas appreciated.
In order your application to read the users it has to have an explicitly granted User.Read.All application permission. This permission requires admin consent. Here is one link where it is explained how to grant that permission. You must invoke that interactive consent dialog to grant your application the permissions. Otherwise you will still receive Insufficient permissions error.
Then here is the complete list of different Microsoft Graph permissions. In your case - a daemon application without user interaction, you have to look at the application permissions and not **delegated permissions*.
Once you grant appropriate permissions, you will be able to query the users. You do not have to change the scope in your token request. Leave it as it is: https://graph.microsoft.com/.default
Once you make all these changes, you can use https://jwt.ms to check your access token. There you can extract all the claims and check your audience and scope claims to further understand why you get 401 from the Microsoft Graph.
The reason for this is the application must also have support for the permissions requested. Case in point is an application isn't allowed to list managed devices as shown in the Prerequisites page in this page
List managedDevices permissions

Why does QueryParam return null

I hava a post method where I try and add the parameter "enc":
protected void sendPost(String url, String encData) throws Exception {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//add request header
con.setRequestMethod("POST");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
// Send post request
con.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write("enc="+encData);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
//System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
}
However in my server code (below) I get a value of NULL when trying to get the data. Its just a string, not JSON or anything fancy. I've also tried writing the param as "?enc="+endData, and that does not work either. Also the path encRead is entered in the url, so I don't think that is the issue.
#Path("/encRead")
#POST
public void decryptData(#QueryParam("enc") String enc) {
System.out.println("got endData: "+enc);
}
So far I've been referencing the answers from Jersey POST Method is receiving null values as parameters but still come up with no solution
The problem is you are trying to write to the body of the request, with wr.write("enc="+encData);. #QueryParams should be in the query string. So this instead would work
public static void main(String[] args) throws Exception {
sendPost(".../encRead", "HelloWorld");
}
protected static void sendPost(String url, String encData) throws Exception {
String concatUrl = url + "?enc=" + encData;
URL obj = new URL(concatUrl);
[...]
//wr.write("enc=" + encData);

code 400 error on post call with android

I am trying to call a WS method from an Android application with POST method.
What I have done:
String urlServer = GlobalSession.IP + "insert_reportByte";
Log.d("[Report]", "url address: " + urlServer);
URL url = new URL(urlServer);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type",
"multipart/form-data");
DataOutputStream outputStream = new DataOutputStream(
connection.getOutputStream());
outputStream.write(outputByteArray, 0, outputByteArray.length);
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
Log.d("ServerCode", "" + serverResponseCode);
Log.d("serverResponseMessage", "" + serverResponseMessage);
outputStream.flush();
outputStream.close();
} catch (Exception ex) {
// ex.printStackTrace();
Log.e("[Report] --- /!\\ Error: ", ex.getMessage());
}
return result;
So I am supposed to send a byte array to the service. But I have a 400 error response. My question is: how to get the details of such an issue? Because I cannot find anything in the logs of the server and it's hard to debug if I do not have the details...
The WS is defined (in ASP.NET) that way:
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "insert_reportByte",
BodyStyle = WebMessageBodyStyle.Bare)]
void insert_reportByte(byte[] image);
And the called method is the following
public void insert_reportByte(byte[] image)
{
MyEntities entities = new MyEntities();
String base64stringimage = System.Convert.ToBase64String(image,0,image.Length);
entities.insert_report("admin", "0614141.107346.2001", "test", base64stringimage, "test");
}
What did I do wrong?
Thank you !
You should change the uploadReadAheadSize and maxReceivedMessageSize parameters on your server applicationHost.config file.
Here you´ve got a thread that talks about it
http://forums.iis.net/t/1169257.aspx?Request+Entity+Too+large+413+error+
This link might be useful too as it explains why you should change the uploadReadAheadSize and maxReceivedMessageSize parameters for better handling of file uploads.
http://www.codeproject.com/Articles/521725/413-Request-Entity-Too-Large
UPDATE
Try using this library for the http calls. It seems that you're sending a bad request to the server. I don't think it has something to do with the parameters that the ws expects but the http headers sent by the android app.
https://github.com/loopj/android-async-http
Hope it helps. :)

Categories