0
votes

This is the error shown while using firebase messaging for push notifications...

Error: Exactly one of topic, token or condition is required
at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28)

    Error: Exactly one of topic, token or condition is required
        at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28)
        at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:88:28)
        at new FirebaseMessagingError (/srv/node_modules/firebase-admin/lib/utils/error.js:254:16)
        at Object.validateMessage (/srv/node_modules/firebase-admin/lib/messaging/messaging-types.js:46:15)
        at Messaging.send (/srv/node_modules/firebase-admin/lib/messaging/messaging.js:208:27)
        at sendNotification (/srv/index.js:227:18)
        at exports.onCreateActivityFeedItem.functions.firestore.document.onCreate (/srv/index.js:197:13)
        at <anonymous>
        at process._tickDomainCallback (internal/process/next_tick.js:229:7)

This is the js code for firebase messaging

exports.onCreateActivityFeedItem = functions.firestore
.document('/feed/{userId}/feedItems/{activityFeedItem}')
.onCreate(async (snapshot, context) => {
    console.log('Activity Feed Item Created', snapshot.data());

This log is printed...

// 1) Get user connected to the feed, 
//send notification if they have token
const userId = context.params.userId;

const userRef = admin.firestore().doc(`users/${userId}`);
const doc = await userRef.get();

// 2) Once we have user check if they have notification item
const androidNotificationToken = doc.data().androidNotificationToken;

const createdActivityFeedItem = snapshot.data();
if (androidNotificationToken) {
    // send notification
    sendNotification(androidNotificationToken, createdActivityFeedItem);
} else {
    console.log('User have no token, cant send notification');
}

function sendNotification(androidNotificationToken, activityFeedItem) {
    let body;
    // switch bod   y value base on notification item (like, comment or follow)
    switch (activityFeedItem.type) {
        case 'comment':
            body = `${activityFeedItem.username} replied: ${activityFeedItem.commentData}`;
            break;
        case 'like':
            body = `${activityFeedItem.username} liked your post.`;
        case 'follow':
            body = `${activityFeedItem.username} followed you.`;
        default:
            break;
    }

    // 4) create message for push notification
    const message = {
        notification: { body },
        token: { androidNotificationToken },
        data: { recipient: userId }
    };

    // 5) send message with admin.messaging
    admin
        .messaging()
        .send(message)
        .then((response) => {
            // Response is a message ID string.
            console.log('Successfully sent message:', response);
        })
        .catch((error) => {
            console.log('Error sending message:', error);
        });

}
});

This is Flutter code

configurePushNotifications() {
    final GoogleSignInAccount user = googleSignIn.currentUser;
    if (Platform.isIOS) {
      getIOSPermission();
    }
    _firebaseMessaging.getToken().then((token) {
      print('Token received: $token');
      usersRef.document(user.id).updateData({
        'androidNotificationToken': token,
      });

      _firebaseMessaging.configure(
        onMessage: (Map<String, dynamic> message) async {
          print('Message is : $message');
          final String recipientId = message['data']['recipient'];
          final String body = message['notification']['body'];

          if (recipientId == user.id) {
            print('Notification Shown');
            SnackBar snackbar = SnackBar(
              content: Text(
                body,
                overflow: TextOverflow.ellipsis,
              ),
            );
            _scaffoldKey.currentState.showSnackBar(snackbar);
          }
          print('Notification not shown');
        },
        //  onResume: (Map<String, dynamic> message) async {},
        //   onLaunch: (Map<String, dynamic> message) async {},
      );
    });
  }

To get ios permission but i am using android phone for debugging

  getIOSPermission() {
    _firebaseMessaging.requestNotificationPermissions(
      IosNotificationSettings(
        alert: true,
        badge: true,
        sound: true,
      ),
    );
    _firebaseMessaging.onIosSettingsRegistered.listen((settings) {
      print('Settings registered: $settings');
    });
  }

onCreateActivityFeedItem Activity Feed Item Created { commentData: 'ab to man ja', mediaUrl: 'https://firebasestorage.googleapis.com/v0/b/chautari-ccfba.appspot.com/o/post_dcc8a054-a972-4b88-8d3f-4802de74393a.jpg?alt=media&token=1120cadb-14cb-4173-a4ec-775290f68fc8', postId: 'dcc8a054-a972-4b88-8d3f-4802de74393a', timeStamp: Timestamp { _seconds: 1589793598, _nanoseconds: 111000000 }, type: 'comment', userId: '116659062086341253410', userProfileImage: 'https://firebasestorage.googleapis.com/v0/b/chautari-ccfba.appspot.com/o/post_profile_pic_postId%3A116659062086341253410.jpg?alt=media&token=8da521ea-2a5e-4833-93b7-9a487afb7be5', username: 'rishi' } 3:23:55.242 PM onCreateActivityFeedItem Error: Exactly one of topic, token or condition is required at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28) at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:88:28) at new FirebaseMessagingError (/srv/node_modules/firebase-admin/lib/utils/error.js:254:16) at Object.validateMessage (/srv/node_modules/firebase-admin/lib/messaging/messaging-types.js:46:15) at Messaging.send (/srv/node_modules/firebase-admin/lib/messaging/messaging.js:208:27) at sendNotification (/srv/index.js:227:18) at exports.onCreateActivityFeedItem.functions.firestore.document.onCreate (/srv/index.js:197:13) at at process._tickDomainCallback (internal/process/next_tick.js:229:7) 3:23:55.258 PM onCreateActivityFeedItem

1
The last section of stuff you pasted in needs formatting and a description. What is it?thelr

1 Answers

0
votes

The error seems to come from the JavaScript code. More precisely, this seems off:

const message = {
    notification: { body },
    token: { androidNotificationToken },
    data: { recipient: userId }
};

If you look at the Firebase documentation on sending a message it contains this example:

var message = {
  data: {
    score: '850',
    time: '2:45'
  },
  token: registrationToken
};

You are wrapping the token in an extra {}, which is not correct as it leads to this JSON: token: { androidNotificationToken: "valueOfandroidNotificationToken" }.

More likely it needs to be:

const message = {
    notification: { body },
    token: androidNotificationToken,
    data: { recipient: userId }
};