android - google - firebase server




يوفر Google Cloud Messaging(GCM) مع مجموعات الأجهزة المحلية على Android رمز خطأ HTTP 401 (2)

أحاول جعل Google Cloud Messaging (GCM) تعمل على نظام Android مع مجموعات الأجهزة المحلية كما هو موضح في https://developers.google.com/cloud-messaging/android/client-device-group .

لقد قمت بتمكين الخدمات التالية في وحدة تحكم الويب ( https://console.developers.google.com ):

  • Google Cloud Messaging لنظام Android
  • Google Cloud Pub / Sub
  • واجهة برمجة تطبيقات + Google

لقد قمت أيضًا بإنشاء بيانات الاعتماد التالية:

  • مفتاح واجهة برمجة التطبيقات (مع اسم الحزمة المحدد ولوحة المفاتيح لشهادة SHA-1)
  • معرفات عميل OAuth 2.0 (تطبيق ويب)

يبدو رمز Android الخاص بي كما يلي (تم التعامل مع الأخطاء وما إلى ذلك):

String account = ACCOUNT_NAME; // E.g. "[email protected]"
String scope = "audience:server:client_id:" + WEB_APPLICATION_CLIENT_ID;
String token = GoogleAuthUtil.getToken(context, account, scope);

// Token is successfully found here :-)

URL url = new URL("https://android.googleapis.com/gcm/notification");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("project_id", NUMERICAL_PROJECT_ID);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.connect();

JSONObject requestBody = new JSONObject();
requestBody.put("operation", "add");
requestBody.put("notification_key_name", "foobar");
requestBody.put("registration_ids", 
  new JSONArray(Arrays.asList(new String[]{"42", "44"})));
requestBody.put("id_token", token);

OutputStream os = connection.getOutputStream();
os.write(requestBody.toString().getBytes("UTF-8"));
os.close();

// connection.getResponseCode() is now 401

يبدو JSON المقدم إلى https://android.googleapis.com/gcm/notification مثل هذا:

{
  "operation": "add",
  "notification_key_name": "foobar",
  "registration_ids": ["42","44"],
  "id_token": "[veeeeeery long string]"
}

محتويات الاستجابة هي:

<HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>

ما الخطأ الذي افعله؟


العثور على الخدعة: أنت تستخدم حساب google لأخذ id_token ، تحتاج إلى استخدام البريد الإلكتروني تمامًا على أنه الإخطار _key_name. لذلك إذا كنت تستخدم [email protected] ، فأنت بحاجة إلى استخدام هذا العنوان كإعلام _key_name.


ها هي الخلاصة ، بناءً على الإجابة الصحيحة من greywolf82. يجب أن تتبع الشفرة الصحيحة هذه المبادئ (جُرِّدت معالجة الأخطاء وما إلى ذلك):

///////////////////////////////////////////////////////////////////////////
// Working example on how to create a locally (client-side) managed      //
// device group for Google Cloud Messaging.                              //
//                                                                       //
// Thanks to greywolf82 for adding the final piece.                      //
// Please vote on his answer. Thank you!                                 //
///////////////////////////////////////////////////////////////////////////

// Get token:
String account = ACCOUNT_NAME; // E.g. "[email protected]"
String scope = "audience:server:client_id:" + WEB_APPLICATION_CLIENT_ID;
String idToken = GoogleAuthUtil.getToken(context, account, scope);

// Get registration id:
InstanceID instanceID = InstanceID.getInstance(this);
String registration_id = instanceID.getToken(
        getString(R.string.gcm_defaultSenderId),
        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

// Set up HTTP connection:
URL url = new URL("https://android.googleapis.com/gcm/googlenotification");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("project_id", NUMERICAL_PROJECT_ID);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.connect();

JSONObject requestBody = new JSONObject();
requestBody.put("operation", "add");
requestBody.put("notification_key_name", ACCOUNT_NAME); // You *must* use the email!
requestBody.put("registration_ids",
    new JSONArray(Arrays.asList(new String[]{registration_id})));
requestBody.put("id_token", idToken);

// Submit request body
OutputStream os = connection.getOutputStream();
os.write(requestBody.toString().getBytes("UTF-8"));
os.close();

// connection.getResponseCode() is now 200  :-)
// Now read the server response contents from connection.getInputStream()

يبدو JSON المقدم إلى https://android.googleapis.com/gcm/notification مثل هذا:

{
  "operation": "add",
  "notification_key_name": "[email protected]",
  "registration_ids": ["very long string here"],
  "id_token": "another very long string"
}

محتويات الاستجابة هي:

{
  "notification_key": "your notification key is here --- voilá!"
}




google-cloud-messaging