0

我试图让下面的代码工作,一年前我上次尝试它时工作得很好。运行它后,我的应用程序中没有收到任何通知。在 ESP32 模块上的 Arduino IDE 中使用。除了更新令牌之外,没有对曾经工作的草图进行任何更改。我没有在串行输出中收到“firebase 错误”消息,因此假设没有错误。

WiFiClient client;
String serve = "MY SERVER KEY";
String appToken = "MY APP TOKEN";
String data = "{";
data = data + "\"to\": \"" + appToken + "\",";
data = data + "\"notification\": {";
data = data + "\"body\": \"example body\",";
data = data + "\"title\" : \"my title\" ";
data = data + "} }";

Serial.println("Send data...");
if (client.connect("fcm.googleapis.com", 80)) {
  Serial.println("Connected to the server..");
  client.println("POST /fcm/send HTTP/1.1");
  client.println("Authorization: key=" + serve + "");
  client.println("Content-Type: application/json");
  client.println("Host: fcm.googleapis.com");
  client.print("Content-Length: ");
  client.println(data.length());
  client.print("\n");
  client.print(data);
  Serial.println("data");
  Serial.println(data);

}
else {
  Serial.println("firebase error");
}
Serial.println("Data sent...Reading response..");
while (client.available()) {
  char c = client.read();
  Serial.print(c);
}
Serial.println("Finished!");
client.flush();
client.stop();
}

我刚刚在我的应用程序中更新了 Firebase 并迁移到了 AndroidX,并且可以接收从 Firebase 控制台发送的消息,我目前正在成功地使用这个库在我的应用程序中发送和接收通知。下面是我正在使用的示例,它运行良好。

#include <WiFi.h>
#include <FirebaseESP32.h>

#define WIFI_SSID "YOUR_WIFI_AP"
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
#define FIREBASE_HOST "YOUR_FIREBASE_PROJECT.firebaseio.com" //Do not include https:// in FIREBASE_HOST
#define FIREBASE_AUTH "YOUR_FIREBASE_DATABASE_SECRET"

#define FIREBASE_FCM_SERVER_KEY "YOUR_FIREBASE_PROJECT_CLOUD_MESSAGING_SERVER_KEY"
#define FIREBASE_FCM_DEVICE_TOKEN_1 "RECIPIENT_DEVICE_TOKEN"
#define FIREBASE_FCM_DEVICE_TOKEN_2 "ANOTHER_RECIPIENT_DEVICE_TOKEN"

FirebaseData firebaseData1;

unsigned long lastTime = 0;

int count = 0;

void sendMessage();

void setup()
{

    Serial.begin(115200);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting to Wi-Fi");
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(300);
    }
    Serial.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
    Firebase.reconnectWiFi(true);

    firebaseData1.fcm.begin(FIREBASE_FCM_SERVER_KEY);

    firebaseData1.fcm.addDeviceToken(FIREBASE_FCM_DEVICE_TOKEN_1);

    firebaseData1.fcm.addDeviceToken(FIREBASE_FCM_DEVICE_TOKEN_2);

    firebaseData1.fcm.setPriority("high");

    firebaseData1.fcm.setTimeToLive(1000);

    sendMessage();
}

void loop()
{

    if (millis() - lastTime > 60 * 1000)
    {
        lastTime = millis();

        sendMessage();
    }
}

void sendMessage()
{

    Serial.println("------------------------------------");
    Serial.println("Send Firebase Cloud Messaging...");

    firebaseData1.fcm.setNotifyMessage("Notification", "Hello World! " + String(count));

    firebaseData1.fcm.setDataMessage("{\"myData\":" + String(count) + "}");

    //if (Firebase.broadcastMessage(firebaseData1))
    //if (Firebase.sendTopic(firebaseData1))
    if (Firebase.sendMessage(firebaseData1, 0))//send message to recipient index 0
    {

        Serial.println("PASSED");
        Serial.println(firebaseData1.fcm.getSendResult());
        Serial.println("------------------------------------");
        Serial.println();
    }
    else
    {
        Serial.println("FAILED");
        Serial.println("REASON: " + firebaseData1.errorReason());
        Serial.println("------------------------------------");
        Serial.println();
    }

    count++;
}

我尝试在前台和后台使用应用程序以数据和通知消息格式发送顶部的代码,但无法接收消息。我想知道 Firebase 格式或规则等是否在去年发生了变化。我需要使用顶部的代码而不是库,因为我可以在消息正文中添加更多的键值对,也可以发送到我过去使用相同代码成功完成的 iOS。我确信密钥对可以添加到我现在正在使用的库中,但我真的更喜欢顶部代码的简单性。将不胜感激任何建议。

4

2 回答 2

0

我不确定,但我相信问题可能是 Arduino 代码是通过 HTTP 而不是 HTTPS 发送的,我在 FB docs 中读到 HTTPS 是必需的。也许他们改变了这一点,因为一年前同样的代码对我来说非常有效。但是我正在将我的代码迁移到 ESP-IDF 的过程中,下面的这个函数正在运行,没有问题,它有轻微的 mods 以符合我在 PlatformIO / VS Code IDE 中使用的 C++。这是唯一改变的事情:

esp_http_client_config_t config = {};
config.url = "https://fcm.googleapis.com/fcm/send";
config.event_handler = _http_event_handler;

我不需要任何类型的 SSL 证书,我只是发送了如图所示的代码。我没有尝试过多地使用 HTTPS 的 Arduino 代码。

static void firebasePost() {
    esp_http_client_config_t config = {}; // important to initialize with "{}" when using C++ on ESP-IDF http client or it will crash easily
    config.url = "https://fcm.googleapis.com/fcm/send";
    config.event_handler = _http_event_handler;
    esp_http_client_handle_t client = esp_http_client_init(&config);
    esp_err_t err = esp_http_client_perform(client);
    const char *post_data = "{\"to\": \"eCiC-20m8Zw:APA91bE4i1rkC(SHORTENED)9JZpbW3gFe5Qfz9BhOFmqua3aeZoDZEQ\",\"notification\": {\"body\": \"Sample Body\",\"title\" : \"Sample Title\"} }";
    esp_http_client_set_header(client, "Authorization", "key=AAAAZrM4XXXX:APA91bFnSr_U15y6mX(SHORTENED)WqaWECxYWaCf_rVPE");
    esp_http_client_set_header(client, "Content-Type", "application/json");
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_post_field(client, post_data, strlen(post_data));
    err = esp_http_client_perform(client);
    if (err == ESP_OK) {
        ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d",
                 esp_http_client_get_status_code(client),
                 esp_http_client_get_content_length(client));
    } else {
        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
    }
    esp_http_client_cleanup(client);
} 
于 2020-01-24T17:57:19.693 回答
0

Arduino Firebase 库通过 SSL 端口 443(HTTPS 方法)连接到 FCM 和 RTDB 的 Firebase。

你上面的假设是不正确的。

您的设备令牌无效或不存在。

您不必知道 Arduino 库中的代码。Google 仅接受对其服务的安全连接。问题可能是设备 uid 或 FCM 有效负载数据的冗余。你用你自己的假设接受你的答案。这个问题没有解决方案。您需要在 GitHub 存储库中打开问题。

于 2020-03-01T06:35:11.350 回答