diff --git a/emission/net/ext_service/push/notify_interface_impl/firebase.py b/emission/net/ext_service/push/notify_interface_impl/firebase.py index f7baf344f..b63add32e 100644 --- a/emission/net/ext_service/push/notify_interface_impl/firebase.py +++ b/emission/net/ext_service/push/notify_interface_impl/firebase.py @@ -33,7 +33,8 @@ def print_dev_flag_warning(): logging.warning("https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages") def map_existing_fcm_tokens(self, token_list): - mapped_token_list = [] + mapped_token_map = {"ios": [], + "android": []} unmapped_token_list = [] for token in token_list: @@ -41,19 +42,20 @@ def map_existing_fcm_tokens(self, token_list): if existing_mapping is not None: assert(existing_mapping["native_token"] == token) mapped_token = existing_mapping["mapped_token"] - logging.debug("mapped %s -> %s" % (token, mapped_token)) - mapped_token_list.append(mapped_token) + mapped_platform = existing_mapping["platform"] + logging.debug("%s: mapped %s -> %s" % (mapped_platform, token, mapped_token)) + mapped_token_map[mapped_platform].append(mapped_token) else: logging.debug("No mapping found for token %s, need to query from database" % token) unmapped_token_list.append(token) - return (mapped_token_list, unmapped_token_list) + return (mapped_token_map, unmapped_token_list) - def retrieve_fcm_tokens(self, token_list): + def retrieve_fcm_tokens(self, token_list, dev): importHeaders = {"Authorization": "key=%s" % self.server_auth_token, "Content-Type": "application/json"} importMessage = { "application": "edu.berkeley.eecs.emission", - "sandbox": False, + "sandbox": dev, "apns_tokens":token_list } logging.debug("About to send message %s" % importMessage) @@ -63,48 +65,60 @@ def retrieve_fcm_tokens(self, token_list): return importedResultJSON def process_fcm_token_result(self, token_list, importedResultJSON): - ret_list = [] + ret_map = {"ios": [], + "android": []} if "results" in importedResultJSON: importedResult = importedResultJSON["results"] for i, result in enumerate(importedResult): if result["status"] == "OK" and "registration_token" in result: - ret_list.append(result["registration_token"]) + ret_map["ios"].append(result["registration_token"]) logging.debug("Found firebase mapping from %s -> %s at index %d"% (result["apns_token"], result["registration_token"], i)); edb.get_push_token_mapping_db().insert({"native_token": result["apns_token"], + "platform": "ios", "mapped_token": result["registration_token"]}) else: logging.debug("Must already be android token, leave it unchanged"); # TODO: Determine whether to store a mapping here or not depending on what the result # for an android token is - ret_list.append(token_list[i]) - return ret_list - - def convert_to_fcm_if_necessary(self, token_list): - (mapped_token_list, unmapped_token_list) = self.map_existing_fcm_tokens(token_list) - importedResultJSON = self.retrieve_fcm_tokens(unmapped_token_list) - newly_mapped_token_list = self.process_fcm_token_result(token_list, importedResultJSON) - return mapped_token_list + newly_mapped_token_list + ret_map["android"].append(token_list[i]) + return ret_map + + def convert_to_fcm_if_necessary(self, token_list, dev): + (mapped_token_map, unmapped_token_list) = self.map_existing_fcm_tokens(token_list) + importedResultJSON = self.retrieve_fcm_tokens(unmapped_token_list, dev) + newly_mapped_token_map = self.process_fcm_token_result(token_list, importedResultJSON) + combo_token_map = {"ios": [], + "android": []} + combo_token_map["ios"] = mapped_token_map["ios"] + newly_mapped_token_map["ios"] + combo_token_map["android"] = mapped_token_map["android"] + newly_mapped_token_map["android"] + return combo_token_map def send_visible_notification(self, token_list, title, message, json_data, dev=False): if len(token_list) == 0: logging.info("len(token_list) == 0, early return to save api calls") return - FirebasePush.print_dev_flag_warning() - # convert tokens if necessary - fcm_token_list = self.convert_to_fcm_if_necessary(token_list) + fcm_token_map = self.convert_to_fcm_if_necessary(token_list, dev) push_service = FCMNotification(api_key=self.server_auth_token) data_message = { "data": json_data, "payload": json_data } - response = push_service.notify_multiple_devices(registration_ids=fcm_token_list, + # Send android and iOS messages separately because they have slightly + # different formats + # https://github.com/e-mission/e-mission-server/issues/564#issuecomment-360720598 + android_response = push_service.notify_multiple_devices(registration_ids=fcm_token_map["android"], data_message=data_message) - logging.debug(response) - return response + ios_response = push_service.notify_multiple_devices(registration_ids=fcm_token_map["ios"], + message_body = message, + message_title = title, + data_message=data_message) + combo_response = {"ios": ios_response, "android": android_response} + logging.debug(combo_response) + return combo_response def send_silent_notification(self, token_list, json_data, dev=False): if len(token_list) == 0: @@ -120,9 +134,8 @@ def send_silent_notification(self, token_list, json_data, dev=False): push_service = FCMNotification(api_key=self.server_auth_token) - FirebasePush.print_dev_flag_warning() # convert tokens if necessary - fcm_token_list = self.convert_to_fcm_if_necessary(token_list) + fcm_token_list = self.convert_to_fcm_if_necessary(token_list, dev) response = push_service.notify_multiple_devices(registration_ids=fcm_token_list, data_message=ios_raw_data, @@ -131,6 +144,10 @@ def send_silent_notification(self, token_list, json_data, dev=False): return response def display_response(self, response): - response_json = response - logging.debug("firebase push result: success %s failure %s results %s" % - (response_json["success"], response_json["failure"], response_json["results"])) + response_ios = response["ios"] + response_android = response['android'] + + logging.debug("firebase push result for ios: success %s failure %s results %s" % + (response_ios["success"], response_ios["failure"], response_ios["results"])) + logging.debug("firebase push result for android: success %s failure %s results %s" % + (response_android["success"], response_android["failure"], response_android["results"]))