Làm cách nào để bạn gửi Thông báo Firebase tới tất cả các thiết bị qua CURL?


84

Tôi đang cố gắng gửi thông báo cho tất cả người dùng ứng dụng (trên Android), về cơ bản là sao chép những gì sẽ xảy ra khi thông báo được gửi qua bảng điều khiển dành cho quản trị viên Firebase. Đây là lệnh CURL mà tôi bắt đầu:

curl --insecure --header "Authorization: key = AIzaSyBidmyauthkeyisfineL-6NcJxj-1JUvEM" --header "Content-Type: application / json" -d "{\" notification \ ": {\" title \ ": \" ghi chú -Title \ ", \" body \ ": \" note-Body \ "}}" https://fcm.googleapis.com/fcm/send

Đây là JSON đã phân tích cú pháp để bạn dễ nhìn hơn:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    }
}

Câu trả lời quay lại chỉ là hai ký tự:

đến

Vậy đó, từ "to". (Tiêu đề báo cáo là 400) Tôi nghi ngờ điều này liên quan đến việc không có "to" trong JSON của tôi. Người ta thậm chí sẽ đặt gì cho một "to"? Tôi không có chủ đề nào được xác định và các thiết bị cũng chưa đăng ký bản thân cho bất cứ thứ gì. Tuy nhiên, họ vẫn có thể nhận được thông báo từ bảng điều khiển quản trị Firebase.

Tôi muốn dùng thử gói JSON "chỉ dữ liệu" do giới hạn đáng kinh ngạc của việc xử lý thông báo Firebase, theo đó nếu ứng dụng của bạn ở nền trước, thì thông báo sẽ được xử lý bởi trình xử lý của BẠN, nhưng nếu ứng dụng của bạn ở chế độ nền, nó sẽ được dịch vụ Firebase xử lý NỘI BỘ và không bao giờ được chuyển đến trình xử lý thông báo của bạn. RIÊNG, điều này có thể được giải quyết nếu bạn gửi yêu cầu thông báo của mình qua API, nhưng CHỈ nếu bạn làm điều đó chỉ với dữ liệu. (Điều này sau đó phá vỡ khả năng xử lý iOS và Android với cùng một thông báo.) Thay thế "thông báo" bằng "dữ liệu" trong bất kỳ JSON nào của tôi không có tác dụng.

Ok, sau đó tôi đã thử giải pháp ở đây: Firebase Java Server để gửi thông báo đẩy tới tất cả các thiết bị mà dường như tôi nói "Ok, mặc dù có thể thông báo cho mọi người qua Bảng điều khiển dành cho quản trị viên ... nhưng không thực sự có thể thông qua API. " Cách giải quyết là yêu cầu mỗi khách hàng đăng ký một chủ đề, sau đó gửi thông báo đến chủ đề đó. Vì vậy, đầu tiên mã trong onCreate:

FirebaseMessaging.getInstance().subscribeToTopic("allDevices");

thì JSON mới mà tôi gửi:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    },
"to":"allDevices"
}

Vì vậy, bây giờ tôi nhận được phản hồi thực sự từ máy chủ. Phản hồi JSON:

{
"multicast_id":463numbersnumbers42000,
"success":0,
"failure":1,
"canonical_ids":0,
"results":
    [
    {
    "error":"InvalidRegistration"
    }
    ]
}

Và điều đó đi kèm với mã HTTP 200. Được rồi ... theo https://firebase.google.com/docs/cloud-messaging/http-server-ref, mã 200 với "InvalidRegistration" có nghĩa là có vấn đề với mã thông báo đăng ký . Có lẽ? Vì phần tài liệu đó dành cho máy chủ nhắn tin. Máy chủ thông báo có giống nhau không? Không rõ. Tôi thấy ở những nơi khác rằng chủ đề có thể mất hàng giờ trước khi nó hoạt động. Có vẻ như điều đó sẽ làm cho việc tạo phòng trò chuyện mới trở nên vô ích, vì vậy điều đó dường như cũng không còn nữa.

Tôi khá hào hứng khi có thể viết mã một ứng dụng từ đầu để nhận thông báo chỉ sau vài giờ khi tôi chưa bao giờ sử dụng Firebase trước đây. Có vẻ như nó còn phải trải qua một chặng đường dài trước khi đạt đến cấp độ của tài liệu Stripe.com.

Điểm mấu chốt: có ai biết JSON cần cung cấp để gửi thông báo tới tất cả các thiết bị chạy ứng dụng phản ánh chức năng Bảng điều khiển dành cho quản trị viên không?


Kiểm tra mã thông báo api của bạn mà bạn đang sử dụng có chính xác không. Ngoài ra, hãy thử gửi tin nhắn GCM đến một thiết bị và xem liệu điều đó có hoạt động hay không. Bạn có thể lấy InstanceId bởi bắt đầu ứng dụng trong debug và đặt một breakpoint trênFirebaseInstanceIdService
Justin Slade

Tôi không thấy "mã thông báo api" hiển thị trong tìm kiếm nhanh trên google về firebase.google.com/docs. Ý bạn là "mã thông báo ID"? hay "Mã thông báo xác thực"? Hay bạn đang nói về khóa ủy quyền của tôi như được cung cấp trong tiêu đề? Đó là một tốt: nếu tôi thay đổi nó từ những gì nó là, phản ứng máy chủ chuyển sang "trái phép" thay vì thông báo lỗi Tôi hiện đang nhận được.
Anders 8

Blog đó dường như là về việc gửi một tin nhắn đến một thiết bị cụ thể, không phải như cuộc thảo luận ban đầu, về việc chỉ gửi nó cho tất cả người dùng của ứng dụng.
Anders 8

Đọc bài đăng trên blog này để biết thêm chi tiết -> developine.com/...
Developine

Câu trả lời:


55

CHỈNH SỬA: Có vẻ như phương pháp này không được hỗ trợ nữa (thx thành @FernandoZamperin). Mời các bạn xem các câu trả lời khác!

Thay vì đăng ký một chủ đề, thay vào đó, bạn có thể sử dụng conditionkhóa và gửi tin nhắn đến các phiên bản không nằm trong một nhóm. Dữ liệu của bạn có thể trông giống như sau:

{
    "data": {
        "foo": "bar"
    },
    "condition": "!('anytopicyoudontwanttouse' in topics)"
}

Xem https://firebase.google.com/docs/cloud-messaging/send-message#send_messages_to_topics_2


3
đó là câu trả lời tốt nhất. Nó có thể chạy ngay lập tức mà không cần cập nhật ứng dụng. tuyệt quá!
Tom Marvolo Riddle

cuối cùng đã tìm thấy một cái - họ thực sự nên làm cho nó rõ ràng hơn khi sử dụng cái đó
cwiesner

Điều này có vẻ hứa hẹn nhưng nó có thực sự hoạt động? Nó trông giống như một vụ hack. Tôi đã thử nó trên một dự án mẫu và nó hoạt động. Tuy nhiên, tôi không chắc liệu nó có hoạt động với ứng dụng sản phẩm có hàng nghìn người dùng đang hoạt động của tôi hay không. Có ai đã thử nó với một ứng dụng sản phẩm?
Sahil Patel

4
Tôi đã sử dụng phương pháp này được một thời gian và hoạt động hoàn hảo, hôm nay vì lý do nào đó tôi gửi thông báo đến api cũ, nó trả lại cho tôi message_id mà không có lỗi, nhưng các thiết bị không nhận được thông báo đẩy, mọi người đoán xem đó sẽ là gì vấn đề? Đã thử nghiệm gửi đến một mã thông báo duy nhất và nó hoạt động bình thường.
Fernando Zamperin

1
@VitVeres Tôi đã gửi một vấn đề tới nhóm hỗ trợ firebase và họ đã trả lời tôi là: "Cách sử dụng biểu thức hiện tại của bạn đối với thông báo đẩy fanout không được hỗ trợ. Hãy đảm bảo rằng các chủ đề được liệt kê trong biểu thức tồn tại cho dự án ứng dụng của bạn.", Vì vậy tôi đoán tôi sẽ phải triển khai các chủ đề trong ứng dụng của mình.
Fernando Zamperin

98

Thông báo của Firebase không có API để gửi tin nhắn. May mắn thay, nó được xây dựng trên nền Firebase Cloud Messaging, có một API chính xác như vậy.

Với Thông báo Firebase và Nhắn tin qua đám mây, bạn có thể gửi cái gọi là tin nhắn xuôi dòng tới các thiết bị theo ba cách:

  1. cho các thiết bị cụ thể , nếu bạn biết ID thiết bị của họ
  2. cho các nhóm thiết bị , nếu bạn biết ID đăng ký của các nhóm
  3. chủ đề , đây chỉ là những chìa khóa mà thiết bị có thể đăng ký

Bạn sẽ lưu ý rằng không có cách nào để gửi đến tất cả các thiết bị một cách rõ ràng. Tuy nhiên, bạn có thể xây dựng chức năng như vậy với từng cái này, ví dụ: bằng cách đăng ký ứng dụng vào một chủ đề khi nó bắt đầu (ví dụ /topics/all:) hoặc bằng cách giữ một danh sách tất cả các ID thiết bị, rồi gửi tin nhắn đến tất cả những người đó.

Để gửi đến một chủ đề, bạn có lỗi cú pháp trong lệnh của mình. Các chủ đề được xác định bằng cách bắt đầu bằng /topics/. Vì bạn không có mã đó trong mã của mình, máy chủ sẽ hiểu allDevicesnhư một id thiết bị. Vì đây là định dạng không hợp lệ cho mã thông báo đăng ký thiết bị, nên nó gây ra lỗi.

Từ tài liệu về cách gửi tin nhắn đến các chủ đề:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/foo-bar",
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

Tôi đã cố gắng gửi {"tới": "/ topic / allDevices", "data": {"message": "Đây là Thông báo về chủ đề Nhắn tin qua đám mây của Firebase!"}} Và nhận được cùng một phản hồi Không hợp lệ. Tôi cho rằng điều đó có nghĩa là chủ đề không hợp lệ. Tôi không thấy cách nào trong bảng điều khiển để xem cơ sở dữ liệu về các chủ đề.
Anders 8

7
/topics/là số nhiều
Frank van Puffelen

nhếch mép Ồ, lỗi đánh máy, lỗi của lập trình viên. ;) Câu trả lời mới là: {"message_id": 5115052numbers95180} trông chắc chắn thành công hơn nhiều. Vì vậy, có vẻ như điểm mấu chốt là mặc dù có một chức năng mạnh mẽ từ bảng điều khiển dành cho quản trị viên để gửi thông báo qua "Thông báo", nhưng KHÔNG có cách nào kích hoạt điều đó từ các lần gửi API và người ta chỉ nên chuyển mình sang sử dụng thông báo. (Mất tính năng lập lịch và theo dõi chuyển đổi được tích hợp trong Thông báo) Tôi sẽ tìm mã nhắn tin để xử lý việc nhận. Cảm ơn Frank. :)
Anders8

1
Uhm ... không hẳn. Bảng điều khiển Thông báo chỉ gửi tin nhắn thông báo (xem phần này tài liệu về các loại thông báo ). Điều duy nhất nó làm mà chúng tôi chưa có API là gửi cho khán giả .
Frank van Puffelen

1
nó cũng tương tự cho iOS? Tôi cố gắng giống nhau và tôi nhận được thông báo khi ứng dụng vẫn còn sống, nhưng ở chế độ nền nó không làm việc
vinbhai4u

71

Cách dễ nhất mà tôi nghĩ ra để gửi thông báo đẩy tới tất cả các thiết bị là đăng ký chúng vào một chủ đề "tất cả" và sau đó gửi thông báo đến chủ đề này. Sao chép điều này trong hoạt động chính của bạn

FirebaseMessaging.getInstance().subscribeToTopic("all");

Bây giờ hãy gửi yêu cầu dưới dạng

{
   "to":"/topics/all",
   "data":
   {
      "title":"Your title",
      "message":"Your message"
      "image-url":"your_image_url"
   }
}

Đây có thể là cách không hiệu quả hoặc không chuẩn, nhưng như tôi đã đề cập ở trên, đó là cách dễ nhất. Vui lòng đăng nếu bạn có bất kỳ cách nào tốt hơn để gửi thông báo đẩy tới tất cả các thiết bị.

Bạn có thể làm theo hướng dẫn này nếu bạn chưa quen với việc gửi thông báo đẩy bằng cách sử dụng Hướng dẫn nhắn tin qua đám mây Firebase - Thông báo đẩy bằng FCM


Để gửi tin nhắn đến một tổ hợp các chủ đề, hãy chỉ định một điều kiện , đó là một biểu thức boolean chỉ định các chủ đề đích. Ví dụ: điều kiện sau sẽ gửi tin nhắn đến các thiết bị được đăng ký TopicAvà một trong hai TopicBhoặc TopicC:

{
   "data":
   {
      "title": "Your title",
      "message": "Your message"
      "image-url": "your_image_url"
   },
   "condition": "'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
}

Đọc thêm về các điều kiện và chủ đề tại đây trên tài liệu FCM


Nó có ý nghĩa với tôi. Nhưng cũng như bạn, tôi không chắc là nó không hiệu quả. Xin vui lòng, ai đó có thể làm rõ nó?
JCarlosR

2
Tôi không nghĩ rằng nó không hiệu quả, đó có thể là cách duy nhất có thể để gửi thông báo đẩy đến tất cả các thiết bị (tôi không thể tìm thấy bất kỳ cách nào khác)
Syed Rafay

1
Câu trả lời tốt nhất! :)
wonsuc

2
Câu trả lời chính xác. Vì nó không được đề cập ở bất cứ đâu nên điều quan trọng là bạn phải biết rằng bạn sẽ nhận được loại thông báo này trong của bạn Serviceđang mở rộng FirebaseMessagingServicetrong #onMessageReceivedhàm. Vì vậy, thông báo không tự động hiển thị, bạn phải tự mình xử lý.
reVerse

4

Một cách để làm điều đó là làm cho tất cả các thiết bị của người dùng của bạn đăng ký một chủ đề. Bằng cách đó, khi bạn nhắm mục tiêu một tin nhắn đến một chủ đề cụ thể, tất cả các thiết bị sẽ nhận được nó. Tôi nghĩ rằng đây là cách phần Thông báo trong bảng điều khiển Firebase thực hiện.


Đọc bài đăng trên blog này để biết thêm chi tiết -> developine.com/...
Developine

2

Tôi đang tìm giải pháp cho thông báo đẩy ứng dụng Ionic Cordova của mình.

Cảm ơn câu trả lời của Syed Rafay.

trong app.component.ts

const options: PushOptions = {
  android: {
    topics: ['all']
  },

trong tệp máy chủ

"to" => "/topics/all",

1

Chỉ cần làm cho tất cả người dùng đăng nhập đăng ký một chủ đề cụ thể, sau đó gửi thông báo đến chủ đề đó.


0

Kiểm tra danh sách chủ đề của bạn trên bảng điều khiển firebase.

  1. Đi tới bảng điều khiển firebase

  2. Nhấp vào Phát triển từ menu bên

  3. Nhấp vào Nhắn tin qua đám mây

  4. Nhấp vào Gửi tin nhắn đầu tiên của bạn

  5. Trong phần thông báo, hãy nhập nội dung nào đó cho Tiêu đề thông báoVăn bản thông báo

  6. Nhấp vào Tiếp theo

  7. Trong phần mục tiêu, nhấp vào Chủ đề

  8. Nhấp vào hộp văn bản Chủ đề tin nhắn , sau đó bạn có thể xem các chủ đề của mình (Tôi không tạo chủ đề có tên là android hoặc ios, nhưng tôi có thể thấy hai chủ đề đó.

  9. Khi bạn gửi thông báo đẩy, hãy thêm điều này làm điều kiện của bạn.

    "condition" => "'tất cả' trong chủ đề || 'android' trong chủ đề || 'ios' trong chủ đề",

Toàn cơ thể

array(
    "notification"=>array(
        "title"=>"Test",
        "body"=>"Test Body",
    ),
    "condition"=> "'all' in topics || 'android' in topics || 'ios' in topics",
);

Nếu bạn có nhiều chủ đề hơn, bạn có thể thêm những chủ đề đó bằng || (hoặc) điều kiện, Sau đó, tất cả người dùng sẽ nhận được thông báo của bạn. Đã thử nghiệm và làm việc cho tôi.


-4

Bạn có thể gửi thông báo đến tất cả các thiết bị bằng "/ chủ đề / tất cả"

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/all",
  "notification":{ "title":"Notification title", "body":"Notification body", "sound":"default", "click_action":"FCM_PLUGIN_ACTIVITY", "icon":"fcm_push_icon" },
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

Đây có phải là chức năng mới không? Hay điều này yêu cầu ứng dụng đăng ký "tất cả"?
Anders 8

Đó là chức năng mặc định. Tôi không đăng ký vào bất kỳ chủ đề nào. Nó làm việc cho tôi. Nhưng tôi đã đăng ký mã thông báo. "getToken"
Siva Karuppiah 20/02/17

1
Bạn sẽ nhận được một ID tin nhắn, vâng, nhưng không có gì được gửi đến bất kỳ thiết bị nào trừ khi bạn có một chủ đề có tên là "tất cả".
Abdalrahman Shatou

Không. Tôi đã nhận được thông báo trong (hai) thiết bị Android của mình. bạn có muốn tôi đính kèm ảnh chụp màn hình của tôi không ?. Tôi xây dựng ứng dụng của mình trên ioinc.
Siva Karuppiah 27/02/17

Điều này làm việc cho tôi. Không biết tại sao điều này bị phản đối.
m1crdy

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.