Reputation: 181
I am trying to create a device Group for a case where the user has multiple devices. I made a map with the device tokens. Now I am wondering if I can use the cloud functions to generate the Device Group token:
Then, listen for changes on the user's 'app_list' map and run something like that on Cloud Functions:
exports.appListAlterado = functions.firestore.document(`usuarios/{idUsuario}`).onUpdate(async (change: any, context: any) => {
const newValue = change.after.data().app_list;
console.log("newValue", newValue);
const regist_ids = [];
for (const idToken of Object.keys(newValue)) {
const appToken = newValue[idToken];
console.log("idToken", idToken);
console.log("appToken", appToken);
regist_ids.push(appToken);
}
console.log("length", regist_ids.length);
console.log("regist_ids", regist_ids);
});
I tried to generate the Device Group token directly from the Android App, but in my tests I was generating a different notification_key each time(maybe I was doing something wrong).
Retrieve notification_key:
public String recuperarChave(String senderId, String userId) throws IOException, JSONException {
Uri.Builder uriBuilded = new Uri.Builder();
uriBuilded.scheme("https").appendQueryParameter("notification_key_name", userId)
.encodedAuthority("fcm.googleapis.com/fcm/notification")
.build();
String buildUrl = uriBuilded.build().toString();
URL url = new URL( buildUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(false);
// HTTP request header
con.setRequestProperty("Authorization", "key=Authorization_Key");
con.setRequestProperty("project_id", senderId);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accent", "application/json");
con.setRequestMethod("GET");
con.connect();
// Read the response into a string
InputStream is = con.getInputStream();
String responseString = new Scanner(is, "UTF-8").useDelimiter("\\A").next();
is.close();
// Parse the JSON string and return the notification key
JSONObject response = new JSONObject(responseString);
return response.getString("notification_key");
}
Creating Device Group:
public String criarGrupo(String senderId, String userId, String registrationId)
throws IOException, JSONException {
URL url = new URL("https://fcm.googleapis.com/fcm/notification");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
// HTTP request header
con.setRequestProperty("Authorization", "key=Authorization_Key");
con.setRequestProperty("project_id", senderId);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("POST");
con.connect();
// HTTP request
JSONObject data = new JSONObject();
data.put("operation", "create");
data.put("notification_key_name", userId);
data.put("registration_ids", new JSONArray(Collections.singletonList(registrationId)));
// Stream
OutputStream os = con.getOutputStream();
os.write(data.toString().getBytes(Charset.forName("UTF-8")));
os.close();
// Read the response into a string
InputStream is = con.getInputStream();
String responseString = new Scanner(is, "UTF-8").useDelimiter("\\A").next();
is.close();
// Parse the JSON string and return the notification key
JSONObject response = new JSONObject(responseString);
return response.getString("notification_key");
}
I also thought on just storing the map with the device's tokens and iterate trough them to send the notifications. But I wonder if it would be a good practice.
So my options would be:
1 - Use the Cloud Functions to listen the database changes, get the list of tokens stored and manage de Device Group creation, add device and remove device.(In that case how it would be done?).
2 - Try to manage de Device Group from the client app.(In documents it seems not recommended).
3 - Iterate the list of tokens and send a message for each one.(In that case, it would be an iteration from a list of users and in each user, iterate in the user's list/map of tokens.
4 - Maybe in a last shot I could use TOPICS. Something like /topics/userId and unsubscribe when user log out.(In that case I wonder if it would be nice have as much topics as I have users. And in case I have more specific topics, it would be a bad practice or create any problems in the future).
I wonder what would be the best approach for my case.
I hope my question is not hard to understand.
Thank You!
Upvotes: 1
Views: 101
Reputation: 5841
I recommend the solution number 3. But you need to restructure your realtime database to be like this.
fcm_tokens
- userid
-device_token1 : fcm token
-device_token2 : fcm token
So when you need to send fcm
to one of your user, you just need to find the userId
of the user, and iterate through the fcm_tokens\userid\
node
Upvotes: 1