diff --git a/push_notifications.admin.inc b/push_notifications.admin.inc
index 5d465b0..23076f3 100644
--- a/push_notifications.admin.inc
+++ b/push_notifications.admin.inc
@@ -212,11 +212,12 @@ function push_notifications_admin_form($form_state) {
   $form['configuration_c2dm']['push_notifications_google_type'] = array(
     '#type' => 'radios',
     '#title' => t('Google Push Notifications Type'),
-    '#description' => t('Google\'s C2DM service (Cloud 2 Device Messaging) was replaced by the Google Cloud Messaging Service. Each services requires a different authentication method. '),
+    '#description' => t('Google\'s GCM service (Google Cloud Messaging) is being replaced by the Firebase Cloud Messaging Service (FCM). Google\'s C2DM service (Cloud 2 Device Messaging) was replaced by the Google Cloud Messaging Service (GCM). Each services requires a different authentication method. '),
     '#default_value' => PUSH_NOTIFICATIONS_GOOGLE_TYPE,
     '#options' => array(
       PUSH_NOTIFICATIONS_GOOGLE_TYPE_C2DM => 'Cloud 2 Device Messaging',
       PUSH_NOTIFICATIONS_GOOGLE_TYPE_GCM => 'Google Cloud Messaging',
+      PUSH_NOTIFICATIONS_GOOGLE_TYPE_FCM => 'Firebase Cloud Messaging'
     ),
   );
 
@@ -261,6 +262,31 @@ function push_notifications_admin_form($form_state) {
     '#default_value' => variable_get('push_notifications_gcm_api_key', ''),
   );
 
+  $form['configuration_c2dm']['fcm_credentials'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Firebase Cloud Messaging'),
+    '#description' => t('Enter your Firebase Cloud Messaging details'),
+    '#attributes' => array(
+      'style' => (PUSH_NOTIFICATIONS_GOOGLE_TYPE != PUSH_NOTIFICATIONS_GOOGLE_TYPE_FCM) ? 'display:none' : '',
+    ),
+
+  );
+
+  $form['configuration_c2dm']['fcm_credentials']['push_notifications_fcm_server_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Server Key'),
+    '#description' => t('Enter the Server Key for your Firebase project'),
+    '#default_value' => variable_get('push_notifications_fcm_server_key', ''),
+    '#maxlength' => 255,
+  );
+
+  $form['configuration_c2dm']['fcm_credentials']['push_notifications_fcm_legacy_server_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Legacy Server key'),
+    '#description' => t('Enter the Legacy Server key for your Firebase project'),
+    '#default_value' => variable_get('push_notifications_fcm_legacy_server_key', ''),
+  );
+
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => 'Save Configuration',
@@ -313,6 +339,8 @@ function push_notifications_admin_form_submit($form, &$form_state) {
       break;
   }
 
+  variable_set('push_notifications_google_type', $form_state['values']['push_notifications_google_type']);
+
   // Set C2DM credentials.
   variable_set('push_notifications_c2dm_username', $form_state['values']['push_notifications_c2dm_username']);
   variable_set('push_notifications_c2dm_password', $form_state['values']['push_notifications_c2dm_password']);
@@ -320,6 +348,10 @@ function push_notifications_admin_form_submit($form, &$form_state) {
   // Set GCM API key.
   variable_set('push_notifications_gcm_api_key', $form_state['values']['push_notifications_gcm_api_key']);
 
+  // Set FCM token.
+  variable_set('push_notifications_fcm_server_key', $form_state['values']['push_notifications_fcm_server_key']);
+  variable_set('push_notifications_fcm_legacy_server_key', $form_state['values']['push_notifications_fcm_legacy_server_key']);
+
   // Set the APNS certificate location.
   $apns_cert_folder = check_plain($form_state['values']['push_notifications_apns_certificate_folder']);
   if (!empty($apns_cert_folder)) {
@@ -405,7 +437,11 @@ function push_notifications_mass_push_form($form_state) {
 
   // Only show Android option if C2DM credentials are available.
   $recipients_options = array('ios' => t('iOS (iPhone/iPad)'));
-  if ((PUSH_NOTIFICATIONS_C2DM_USERNAME && PUSH_NOTIFICATIONS_C2DM_PASSWORD) || PUSH_NOTIFICATIONS_GCM_API_KEY) {
+  if (
+    (PUSH_NOTIFICATIONS_C2DM_USERNAME && PUSH_NOTIFICATIONS_C2DM_PASSWORD) ||
+    PUSH_NOTIFICATIONS_GCM_API_KEY ||
+    PUSH_NOTIFICATIONS_FCM_SERVER_KEY
+  ) {
     $recipients_options['android'] = t('Android');
   }
   $form['recipients'] = array(
@@ -506,6 +542,10 @@ function push_notifications_mass_push_form_submit($form, &$form_state) {
         case PUSH_NOTIFICATIONS_GOOGLE_TYPE_GCM:
         $result = push_notifications_gcm_send_message($tokens_android, $payload);
         break;
+
+        case PUSH_NOTIFICATIONS_GOOGLE_TYPE_FCM:
+          $result = push_notifications_fcm_send_message($tokens_android, $payload);
+          break;
       }
       $dsm_type = ($result['success']) ? 'status' : 'error';
       drupal_set_message($result['message'], $dsm_type);
diff --git a/push_notifications.install b/push_notifications.install
index fbcaca4..248c27f 100644
--- a/push_notifications.install
+++ b/push_notifications.install
@@ -41,6 +41,10 @@ function push_notifications_uninstall() {
   variable_del('push_notifications_gcm_project_id');
   variable_del('push_notifications_gcm_api_key');
   variable_del('push_notifications_gcm_server_post_url');
+  variable_del('push_notifications_fcm_sender_id');
+  variable_del('push_notifications_fcm_server_key');
+  variable_del('push_notifications_fcm_legacy_server_key');
+  variable_del('push_notifications_fcm_server_post_url');
   variable_del('push_notifications_privatemsg_integration');
   variable_del('push_notifications_require_enabled_language');
 }
diff --git a/push_notifications.module b/push_notifications.module
index 9586332..7d1728f 100644
--- a/push_notifications.module
+++ b/push_notifications.module
@@ -48,6 +48,7 @@ define('PUSH_NOTIFICATIONS_APNS_STREAM_CONTEXT_LIMIT', variable_get('push_notifi
 // 1 => Google Cloud Messaging
 define('PUSH_NOTIFICATIONS_GOOGLE_TYPE_C2DM', 0);
 define('PUSH_NOTIFICATIONS_GOOGLE_TYPE_GCM', 1);
+define('PUSH_NOTIFICATIONS_GOOGLE_TYPE_FCM', 2);
 define('PUSH_NOTIFICATIONS_GOOGLE_TYPE', variable_get('push_notifications_google_type', PUSH_NOTIFICATIONS_GOOGLE_TYPE_GCM));
 
 //
@@ -68,6 +69,16 @@ define('PUSH_NOTIFICATIONS_GCM_API_KEY', variable_get('push_notifications_gcm_ap
 // GCM Server Post URL
 define('PUSH_NOTIFICATIONS_GCM_SERVER_POST_URL', variable_get('push_notifications_gcm_server_post_url', 'https://android.googleapis.com/gcm/send'));
 
+//
+// FCM Variables
+//
+// FCM Cloud Messaging TokenSender ID
+define('PUSH_NOTIFICATIONS_FCM_SERVER_KEY', variable_get('push_notifications_fcm_server_key', ''));
+// FCM Cloud Messaging Server Key
+define('PUSH_NOTIFICATIONS_FCM_LEGACY_SERVER_KEY', variable_get('push_notifications_fcm_legacy_server_key', ''));
+// FCM Server Post URL
+define('PUSH_NOTIFICATIONS_FCM_SERVER_POST_URL', variable_get('push_notifications_fcm_server_post_url', 'https://fcm.googleapis.com/fcm/send'));
+
 
 /**
  * Implements of hook_menu().
@@ -589,7 +600,11 @@ function push_notifications_send_alert($tokens = array(), $payload = array()) {
   }
 
   // Send payload to Android recipients if configured correctly.
-  if (!empty($tokens_android) && ((PUSH_NOTIFICATIONS_C2DM_USERNAME && PUSH_NOTIFICATIONS_C2DM_PASSWORD) || PUSH_NOTIFICATIONS_GCM_API_KEY)) {
+  if (!empty($tokens_android) && (
+      (PUSH_NOTIFICATIONS_C2DM_USERNAME && PUSH_NOTIFICATIONS_C2DM_PASSWORD) ||
+      PUSH_NOTIFICATIONS_GCM_API_KEY ||
+      PUSH_NOTIFICATIONS_FCM_SERVER_KEY
+    )) {
     // Determine which method to use for Google push notifications.
     switch (PUSH_NOTIFICATIONS_GOOGLE_TYPE) {
       case PUSH_NOTIFICATIONS_GOOGLE_TYPE_C2DM:
@@ -599,6 +614,10 @@ function push_notifications_send_alert($tokens = array(), $payload = array()) {
       case PUSH_NOTIFICATIONS_GOOGLE_TYPE_GCM:
         push_notifications_gcm_send_message($tokens_android, $payload);
         break;
+
+      case PUSH_NOTIFICATIONS_GOOGLE_TYPE_FCM:
+        push_notifications_fcm_send_message($tokens_android, $payload);
+        break;
     }
   }
 }
@@ -993,6 +1012,121 @@ function push_notifications_gcm_send_message($tokens, $payload) {
   return $result;
 }
 
+/**
+ * Send out push notifications through FCM.
+ *
+ * @link https://firebase.google.com/docs/cloud-messaging/
+ *
+ * @param $tokens
+ *   Array of fcm tokens
+ * @param $payload
+ *   Payload to send.
+ *
+ * @return
+ *   Array with the following keys:
+ *   - count_attempted (# of attempted messages sent)
+ *   - count_success   (# of successful sends)
+ *   - success         (# boolean)
+ *   - message         (Prepared result message)
+ */
+function push_notifications_fcm_send_message($tokens, $payload) {
+  if (!is_array($tokens) || empty($payload) || (is_array($tokens) && empty($tokens))) {
+    return FALSE;
+  }
+
+  // Define an array of result values.
+  $result = array(
+    'count_attempted' => 0,
+    'count_success' => 0,
+    'success' => 0,
+    'message' => '',
+  );
+
+  // Define the header.
+  $headers = array();
+  $headers[] = 'Content-Type:application/json';
+  $headers[] = 'Authorization: key=' . PUSH_NOTIFICATIONS_FCM_SERVER_KEY;
+
+  // Check of many token bundles can be build.
+  $token_bundles = ceil(count($tokens) / 1000);
+  $result['count_attempted'] = count($tokens);
+
+  // Send a push notification to every recipient.
+  for ($i = 0; $i < $token_bundles; $i++) {
+    // Create a token bundle.
+    $bundle_tokens = array_slice($tokens, $i * 1000, 1000, FALSE);
+
+    // Convert the payload into the correct format for C2DM payloads.
+    // Prefill an array with values from other modules first.
+    $data = array();
+    foreach ($payload as $key => $value) {
+      if ($key != 'alert') {
+        $data['data'][$key] = $value;
+      }
+    }
+    // Fill the default values required for each payload.
+    $data['registration_ids'] = $bundle_tokens;
+    $data['collapse_key'] = (string) time();
+    $data['notification']['body'] = $payload['alert'];
+
+    $curl = curl_init();
+    curl_setopt($curl, CURLOPT_URL, PUSH_NOTIFICATIONS_FCM_SERVER_POST_URL);
+    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+    curl_setopt($curl, CURLOPT_POST, TRUE);
+    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
+    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
+    $response_raw = curl_exec($curl);
+    $info = curl_getinfo($curl);
+    curl_close($curl);
+
+    $response = FALSE;
+    if (isset($response_raw)) {
+      $response = json_decode($response_raw);
+    }
+
+    // If Google's server returns a reply, but that reply includes an error,
+    // log the error message.
+    if ($info['http_code'] == 200 && (!empty($response->failure))) {
+      watchdog('push_notifications', "Google's Server returned an error: " . $response_raw, NULL, WATCHDOG_ERROR);
+
+      // Analyze the failure.
+      foreach ($response->results as $token_index => $message_result) {
+        if (!empty($message_result->error)) {
+          // If the device token is invalid or not registered (anymore because the user
+          // has uninstalled the application), remove this device token.
+          if ($message_result->error == 'NotRegistered' || $message_result->error == 'InvalidRegistration') {
+            push_notifications_purge_token($bundle_tokens[$token_index], PUSH_NOTIFICATIONS_TYPE_ID_ANDROID);
+            watchdog('push_notifications', 'FCM token not valid anymore. Removing token ' . $bundle_tokens[$token_index]);
+          }
+        }
+      }
+    }
+
+    // Count the successful sent push notifications if there are any.
+    if ($info['http_code'] == 200 && !empty($response->success)) {
+      $result['count_success'] += $response->success;
+    }
+  }
+
+  $result['message'] = t('Successfully sent !count_success Firebase Cloud Messages (attempted to send !count messages).', array('!count_success' => $result['count_success'], '!count' => $result['count_attempted']));
+  $result['success'] = TRUE;
+
+  // Invoke rules.
+  if (module_exists('rules')) {
+    rules_invoke_event_by_args('push_notifications_after_fcm_send', array(
+        'type_id' => PUSH_NOTIFICATIONS_TYPE_ID_ANDROID,
+        'payload' => $payload,
+        'count_attempted' => $result['count_attempted'],
+        'count_success' => $result['count_success'],
+        'success' => $result['success'],
+        'result_message' => $result['message'],
+      )
+    );
+  }
+
+  return $result;
+}
 
 /**
  * Determine all recipients from a specific device type.
diff --git a/push_notifications_admin.js b/push_notifications_admin.js
index 6dc092a..8b5e7e7 100644
--- a/push_notifications_admin.js
+++ b/push_notifications_admin.js
@@ -1,14 +1,23 @@
 (function ($) {
   $(document).ready(function(){
-    // Only show options for either C2DM or GCM.
+    // Only show options for C2DM, GCM or FCM.
   	$('input#edit-push-notifications-google-type-0').click(function(e) {
       $('fieldset#edit-c2dm-credentials').show();
       $('fieldset#edit-gcm-credentials').hide();
+      $('fieldset#edit-fcm-credentials').hide();
   	});
     
   	$('input#edit-push-notifications-google-type-1').click(function(e) {
       $('fieldset#edit-c2dm-credentials').hide();
-      $('fieldset#edit-gcm-credentials').show();      
-  	});    
+      $('fieldset#edit-gcm-credentials').show();
+      $('fieldset#edit-fcm-credentials').hide();
+    });
+
+    $('input#edit-push-notifications-google-type-2').click(function(e) {
+      $('fieldset#edit-c2dm-credentials').hide();
+      $('fieldset#edit-gcm-credentials').hide();
+      $('fieldset#edit-fcm-credentials').show();
+    });
+
   });  
 })(jQuery);
\ No newline at end of file
