bytefish / FcmSharp

Firebase Cloud Messaging (FCM) with .NET
MIT License
6 stars 7 forks source link

Exception: Invalid value at 'message' (oneof), oneof field 'target' is already set. Cannot set 'topic' #14

Closed icebeam7 closed 6 years ago

icebeam7 commented 6 years ago

If I include both the Topic and Token inside the Message, the notification is not sent.

If I set the Topic only, it does not work as well.

If I set the Token only, the notification is sent (and received on the device).

Is this an expected behaviour? I'm not a Firebase expert, so pardon my ignorance about it.

My code is as follows (it's a Web API ASP .NET Core project):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

using System.Threading;
using FcmSharp.Requests;
using FcmSharp.Settings;
using FcmSharp;

namespace DemoWebApi2.Controllers
{
[Route("api/Notifications")]
public class NotificationsController : Controller
{
    [HttpPost]
    public async Task Post([FromBody]Models.Message msg)
    {
            var settings = FileBasedFcmClientSettings.CreateFromFile("demoluis-bbb4b", "serviceAccount.json");

            using (var client = new FcmClient(settings))
            {
                var data = new Dictionary<string, string>()
                {
                    {"message", msg.Text}
                };

                var message = new FcmMessage()
                {
                    ValidateOnly = false,
                    Message = new Message
                    {
                        Token = msg.Token,
                        //Topic = msg.Topic,
                        Data = data
                    }
                };

                try
                {
                    CancellationTokenSource cts = new CancellationTokenSource();
                    var result = await client.SendAsync(message, cts.Token);
                }
                catch(Exception {  }
            }
        }
    }
}
bytefish commented 6 years ago

No worries. The Token is always for a specific device, it is an unicast message. A topic is for multiple devices and no, it's not included in a Token. You can only set one of the two. Either you send a message to a single device (using the token) or you send it to mulitple devices (using a topic).

The library does not validate if the message is sound, I could add a Builder, that validates such errors. But I don't have time right now. For now please keep in mind to only set only one of the two values.

icebeam7 commented 6 years ago

Thanks for the concise explanstion. I get it. Well in that case I need to send the notification to several devices so I have to make it work with Topic.

Do you have any idea why the notification is not sent when the Topic is included only as I said before? I mean, I use the same code.

I'll try something else later as well.

Thanks.

bytefish commented 6 years ago

Not really. I have tried the Topic messages with the quickstart messaging example explained in the README. Did you try it? Maybe it is a good starting point. Probably the Client didn't register correctly or a typo? 🤔

bytefish commented 6 years ago

The old Firebase Cloud Messaging API had the notion of Device Groups for grouping devices (https://firebase.google.com/docs/cloud-messaging/android/device-group). Maybe it can be simulated with Topics. If I find it out, I will let you know through this issue.

icebeam7 commented 6 years ago

Ok, I just found the problem. There was no suscription to the Topic in the Android app. The notification was actually being sent by using the topic, but no device got the message since no one was subscribed to it. After adding the code in Android, the notification was received.

So Topic is working now for me.

Thanks :)

bytefish commented 6 years ago

Great to hear! Thanks for the feedback.

Ahmed-Ouf commented 5 years ago

wheni user Token ="IOS_Device_token", return "code": 400, "message": "Request contains an invalid argument.",, var settings = FileBasedFcmClientSettings.CreateFromFile("mostafed-eb19f", @"C:\Work\Firebase\service.json");

        // Construct the Client:
        using (var client = new FcmClient(settings))
        {

            // The Message should be sent to the News Topic:g
            var message = new FcmMessage
            {
                ValidateOnly=true,

                Message = new Message
                {
                    //Topic= "DEFAULT_TOPIC",
                    Token = "CE4E8DD36FCEA2D31CC51AD01CC7B7BC70347C9016C4C610012D1902324xxxxx",
                    Notification = new Notification
                    {
                        Body = "Title",
                        Title = "Body"
                    }
                }
            };

            // Finally send the Message and wait for the Result:
            CancellationTokenSource cts = new CancellationTokenSource();
            // Send the Message and wait synchronously:
            var result = client.SendAsync(message, cts.Token).GetAwaiter().GetResult();

            // Print the Result to the Console:
            System.Console.WriteLine("Message ID = {0}", result.Name);

            System.Console.ReadLine();`

And If i use topic , the result be Message ID = projects/mostafed-eb19f/messages/5392577478766955967 but not affected in (Firebase Console app ) and not notification appear at IOS app , image

bytefish commented 5 years ago

Why do you set ValidateOnly to true? Set it to false and it will actually send the message.

Ahmed-Ouf commented 5 years ago

Why do you set ValidateOnly to true? Set it to false and it will actually send the message.

I changed it but stile that exception appear ?!

bytefish commented 5 years ago

Don't set the Notification Text to "Title" or "Body". These may be reserved keywords. Then make sure the Token you are using is valid. Invalid Tokens will also lead to a 400 Error.

Ahmed-Ouf commented 5 years ago

Don't set the Notification Text to "Title" or "Body". These may be reserved keywords. Then make sure the Token you are using is valid. Invalid Tokens will also lead to a 400 Error.

Thanks its work correctly, The root cause is the Token , FCM need its FCM_Token Not APNS_device_Token 👍

kehollin commented 5 years ago

One thing I discovered is that the "deviceToken: Data" parameter in the AppDelegate method application

didRegisterForRemoteNotificationsWithDeviceToken is NOT the FCM token (not sure why I expected it to be). You need to call InstanceID.instanceID(). token() to get the FCM token.

Kevin Hollingshead Research Software Engineer

Arizona State University College of Health Solutions School of Nutrition and Health Promotion 602-615-9972 (cell)

On Mon, Nov 19, 2018 at 12:13 AM Ahmed-Ouf notifications@github.com wrote:

Don't set the Notification Text to "Title" or "Body". These may be reserved keywords. Then make sure the Token you are using is valid. Invalid Tokens will also lead to a 400 Error.

Thanks its work correctly, The root cause is the Token , FCM need its FCM_Token Not APNS_device_Token 👍

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bytefish/FcmSharp/issues/14#issuecomment-439793006, or mute the thread https://github.com/notifications/unsubscribe-auth/AExGMX8WPwMXjNq5Zj8EIlG5jEwZcWxuks5uwloDgaJpZM4UWrtx .

bytefish commented 5 years ago

@Ahmed-Ouf Great you figured it out! @kehollin Interesting find, I will later compile a list with such hints into the Wiki.