GCM Diagnostics shows messages only for production package name - android

How can I have GCM diagnostic information for a develop version of an app?
The GCM Diagnostics page, under https://play.google.com/apps/publish/, correctly shows message information when I send messages to the main package, but not when .debug is added as a suffix. I can successfully send messages to either app using the same API key and the appropriate Registration ID. For reference here is my test message sending code, straight from the quickstart example.
// Create connection to send GCM Message request.
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key=" + API_KEY);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// Send GCM message content.
OutputStream outputStream = conn.getOutputStream();
outputStream.write(jGcmData.toString().getBytes());
Interestingly both of the Registration IDs end up being mapped together and the dashboard returns only the one message sent to the the app with the production package name.

Related

Get 403 response with the "new" Firebase Cloud Messaging API

We are successfully using the Legacy HTTP Server Protocol on our server for FCM.
I wanted to update to FCM HTTP v1 API today.
I did it step by step and when the server calls the request, we get this response:
Server returned HTTP response code: 403 for URL: https://fcm.googleapis.com/v1/projects/[projectid]/messages:send
This is the server code:
URL url = new URL("https://fcm.googleapis.com/v1/projects/[projectid]/messages:send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Bearer " + getAccessToken());
conn.setRequestProperty("Content-Type", "application/json");
OutputStream outputStream = conn.getOutputStream();
outputStream.write(req.getBytes("UTF-8"));
// Exception happen here
InputStream inputStream = conn.getInputStream();
The getAccessToken():
private static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream(ClientApiServlet.context.getRealPath("/WEB-INF/[projectid].json"))) .createScoped(Arrays.asList("https://www.googleapis.com/auth/firebase.messaging"));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}
I have downloaded the json file from the adminsdk page of the firebase cloud.
All with the same projectid...
I updated these 2 libs on the server:
google-http-client-jackson2-1.23.0.jar
google-oauth-client-1.23.0.jar
The getAccessToken() methode returned an accesstoken: "ya29.c.Elr0BAa..."
I think, I miss a small step, maybe you could help?
Thanks in advance!
Edit:
It is working now with the hint of arterpa! Thanks again!
After that I got a 400 error, so something in the request data was wrong:
The problem was, we didn't converted all data{...}values to strings. With the legacy protocol it was not an issue, but with FCM HTTP v1 API it has to be strings! ;)
I had this problem, and it seems you need to enable FCM API for your project at Google API console.
I was having this issue of getting a 403 from the FCM HTTP v1 API. I had FCM Messaging API enabled, but my problem was that the service account I was using didn't have the correct role to make requests to the FCM API. You can try creating a new service account with the "project Owner" role to see if that helps.

How to go for refresh token automatically when access token expired and get 401 using HttpURLConnection in android?

I have post request like below, Cant we make it automatic like Retrofit 2.0 interceptor if access token expires get refresh token and service call continues? without interruption?
URL url = new URL(myurl + "?access_token=" + access_token);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(100000000 /* milliseconds */);
conn.setConnectTimeout(150000000 /* milliseconds */);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("charset", "utf-8");
conn.setDoInput(true);
conn.connect();
Is there any method to do this automatically when we get 401 response code ?
As far as i know, No way is provided for this in any framework as this is purely requirement based. You will have to post SERIAL calls as stated below :
Post Main Call with Access Token; Iff successful than Stop Else go to Step2
Post Call for New Access Token with Refresh Token, If Successful Update access token and again Post Main call like step 1 with updated Access token.
Same way if your refresh token can expire, than handle that in same SERIAL Way.
Hope it helps a bit.

GCM Client Based Device Group Management

I'm having issues adding GCM registration ID's to a device group client side in my Android app. I've followed all the instructions from https://developers.google.com/cloud-messaging/android/client-device-group but keep getting a 401 HTTP response. I've found the following posts but no one has an answer...
get notification key error 401 gcm https://android.googleapis.com/gcm/googlenotification
Google Cloud Messaging, returning 401 Unauthorized
Google Cloud Messaging, 401 Unauthorized is returned when creating notification key from client
How to successfully "Generate a Notification Key on the Client" with GCM?
I'm successfully getting an auth token from GoogleSignInApi and the method provided in Google's instructions but both give back 401 responses. I've ensured that I'm using the client ID for a Web Application in my Google Developer Console and still no luck. Here is my code snippet...
URL url = new URL("https://android.googleapis.com/gcm/googlenotification");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
// HTTP request header
con.setRequestProperty("project_id", getString(R.string.gcm_defaultSenderId));
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("POST");
con.connect();
String accountName = getAccount();
//Initialize the scope using the client ID you got from the Console.
final String scope = "audience:server:client_id:"
+ "MY_WEB_APP_CLIENT_ID";
String idToken = "";
try {
idToken = GoogleAuthUtil.getToken(this, sharedPref.getString("googleEmail", ""), scope);
} catch (Exception e) {
e.printStackTrace();
}
// HTTP request
JSONObject data = new JSONObject();
data.put("operation", "add");
data.put("notification_key_name", "my_group_name");
data.put("registration_ids", new JSONArray(Arrays.asList(registrationId)));
data.put("id_token", idToken);
OutputStream os = con.getOutputStream();
os.write(data.toString().getBytes("UTF-8"));
os.close();
int responseCode = con.getResponseCode();
I don't think it matters for this HTTP post request but I've also ensured the right project and client ID (android) are stored in my google-services.json. Has anyone had any success managing device groups client side? If so what's different in my code from yours?
I'm not sure that it is possible to do this without the server API key. The 401 error indicates that some sort of HTTP Authorization header should be included if that URL is used for device group setup.
My best suggestion is to keep the server API key well hidden using a client-side keystore mechanism (http://developer.android.com/training/articles/keystore.html).
For details on how do do the whole thing using the SERVER_API key, please see here: Google Cloud Messaging (GCM) with local device groups on Android gives HTTP Error code 401
Hope this helps. :-)

Setting the oauth "Authorization"header in Java - Android

I'm trying to set the access token with all of my network calls in my Android app.
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Token token="
+ accessToken);
conn.setRequestMethod("GET");
With this code, however, the header that our server is seeing is "HTTP_AUTHORIZATION" - not "AUTHORIZATION". After pouring over javadocs, I can't figure out how to not get it to append the "HTTP_".
Thanks!
You can't. The mapping of Authorization to HTTP_AUTHORIZATION is part of the CGI Specification and happens on the server.

Confuse of Push Notification in Android

I followed this Push Notification tutorial.
When I finish the tutorial, I found out that two classes did not use which were AuthenticationUtil and MessageUtil.
Moreover, Google Login, this link seem unworkable. Second, This is the token id for the Android device or the account only? i thought push notification is push message to token id of Android device.
On the others hand, i found out that the bundle.putExtra(key, value), all the keys did not use it. For example put "app" but in C2DMRegistrationReceiver() did not get the key.
In this sendRegistrationIdToServer(), it seem like never being call out.
I am being confused by this tutorial about push notification.
Who can guide me or give me workable tutorial or example about push notification?
I would like pro to point out what's my wrong.
This is my registration id
public static final String[] REGISTRATION_ID = {
"APA91bFV6MwoAH0UNop69PZ2liKpSBUHSHenIuPzh44_6GdGKzVCLvoH_NM31eMZMVLZi-SAIFwP4iZaE72dSWkIh3GaD0RQYpPm9zO0ARWmnoxFyyyreL_KpQ9Qd_p0broclT12RhA4Ymk0cBT00CmpsbSHIwyxig",
"APA91bEwmxgvs7zNbKC4p0n4DoTEM73DTihnQgBOP8Gxhf2sVW-fgltugDgS1Fh2S4KvN1wQHbMNJEIzieJ9F1nNPqs3NWeKGbB7IBYpKJq4xmN4Z7uzkjZQQUKGD8jW--AwfQY5McINBto9GAL_87_u5WkIq-kx3g",
"APA91bH63Zgxn1X_MZ56UzrlRpffvmiLAIsqxvBUTMUHP2O_MT_VU9Ork_edXKHlml-PZSkjKEqdk8EKv5HvxbPdK1Vva3WtmqsPZfhXzEbtNIrwrqIvvRf7hL835rDc4t2E8EKUBj1dX2ta0OxY5pY3Xlhkyb1sBg",
"APA91bGqT5Wo6eUaMdqT5r9TlGbKSX6GN2W6r-RjrRXz5T5v3j87flcQRyfSajmMNGXuPVe-fwZydRmvyYu63tWnYohDmpJyKkXOxs8Vx6P_FplFQ__ufR_hekwqGOspeUc6bfc8fhbMPGN3Ft9l-bfrghJwwk79jw"};
Messageutil
public static int sendMessage(String auth_token, String registrationId,
String message, String title) throws IOException {
StringBuilder postDataBuilder = new StringBuilder();
postDataBuilder.append(PARAM_REGISTRATION_ID).append("=")
.append(registrationId);
postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=")
.append("0");
postDataBuilder.append("&").append("data.payload").append("=")
.append(URLEncoder.encode(message, UTF8));
postDataBuilder.append("&").append("data.title").append("=")
.append(URLEncoder.encode(title, UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
// Hit the dm URL.
URL url = new URL("https://android.clients.google.com/c2dm/send");
HttpsURLConnection
.setDefaultHostnameVerifier(new CustomizedHostnameVerifier());
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
conn.setRequestProperty("Content-Length",
Integer.toString(postData.length));
conn.setRequestProperty("Authorization", "GoogleLogin auth="
+ auth_token);
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
int responseCode = conn.getResponseCode();
return responseCode;
}
private static class CustomizedHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
Messagesender
public static void main(String[] args) throws IOException {
String token = AuthenticationUtil.getToken(SecureStorage.USER,
SecureStorage.PASSWORD);
for (int i = 0; i < ServerConfiguration.REGISTRATION_ID.length; i++) {
MessageUtil.sendMessage(token,
ServerConfiguration.REGISTRATION_ID[i], "12358",
"印尼羽賽:馬2單1雙止步入選賽");
System.out.println(ServerConfiguration.REGISTRATION_ID[i]
.toString());
}
System.out.println(token);
}
You should follow this tutorial for android c2dm implementation.
For server, you could use anything, some code sample available on internet. For server I used .NET library called "C2DM Sharp"
The process is very simple like...
First register your google email for c2dm on - https://developers.google.com/android/c2dm/signup
Run the android application on Android 2.2 or higher and send the registrationID which you can get in "C2DMReceiver" or get that ID by writting in LOG
Use the server code, for testing purpose paste your registrationID in Server code and you are ready to go.
The basic flow of C2DM is ...
Register Phone for C2DM -> Get registrationID -> Send registrationID to server -> Server usees google id to get auth token -> server use registrationID and auth token to send message.
Google Cloud Messaging for Android
Important: C2DM(Android Cloud to Device Messaging Framework) has been officially deprecated as of June 26, 2012. This means that C2DM has stopped accepting new users and quota requests. No new features will be added to C2DM. However, apps using C2DM will continue to work. Existing C2DM developers are encouraged to migrate to the new version of C2DM, called Google Cloud Messaging for Android (GCM). See the C2DM-to-GCM Migration document for more information. Developers must use GCM for new development.
Kindly check the following link:
http://developer.android.com/guide/google/gcm/index.html
Please see my question here:
C2DM server. Should we use OAuth now?
There is some info and link to google group with answer.
In short..
Seems like OAuth2 will work, but I didn't find any working sample to implement
Client Login works and this is place where my confusion was. You need to:
Set up google account. I picked something like mynamec2dm#gmail.com.
Register for C2DM using this email. This is important.
On server-side use email/password you setup to get auth token.
Use this token to send messages from server.
Everything else is just like in all tutorials around.

Categories

Resources