vesii
vesii

Reputation: 3128

Error: Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string

I spend too much time on trying to figure out on how FCM works so I'm looking for some wisdom. I'm trying to add push notifications for my app using Firebase Cloud messaging (FCM). I read the docs but I'm don't fully understand how it works. My app is written in Java and for the messaging I want to use javascript. In my app I have a chat rooms where users can communicate. I want to set a push notification once he gets a new message. In order to get to the chat room, the path in the database:

groups (collection) -> <group name> (document) -> chatRooms (collection) -> <chat ID> (document) -> roomMessages (collection) -> <message ID> (document)

Each document in the chatRooms collection contains the following fields:

  1. name - name of the room.
  2. lastMeesage - The last message that was sent in the chat room (updated once the message is sent).
  3. lastMessageTimestamp - The timestamp of the last message.
  4. users - Array of users (paths) that are talking in the chat room.

Each document in the roomMessages collection contains the following fields:

  1. message - The message that was sent.
  2. userName - The user name.
  3. userPath - The path to the user document in the firebase.
  4. timestamp - The timestamp of the message.

I was following this tutorial on how to do it. I wrote the following code:

const functions = require('firebase-functions');
const admin     = require('firebase-admin');

admin.initializeApp();
const db = functions.firestore;

exports.onMessageSent = db.document(`groups/{groupName}/chatRooms/{chatId}/roomMessages/{messageId}`).onCreate((messageDoc, context) => {
    const message = messageDoc.message;
    const senderName = messageDoc.senderName;
    const senderPath = messageDoc.senderPath;
    const chatId = context.params.chatId;
    const groupName = context.params.groupName;
    const groupPath = 'groups/' + groupName;

    return admin.firestore().doc(senderPath).get().then(senderDoc => {
        var senderPhoto = null;
        if (typeof senderDoc.data().image !== 'undefined') {
            senderPhoto = senderDoc.data().image;
        }
        return admin.firestore().doc(`groups/${groupName}/chatRooms/${chatId}`).get().then(chatRoomDoc => {
            return chatRoomDoc.data().users.forEach((userPath, index) => {
                return admin.firestore().doc(userPath).get().then(receiverDoc => {
                    console.log('Creating a chat notification for: ', receiverDoc.data().full_name);

                    let tokens = receiverDoc.data().tokens;
                    const payload = {
                        data: {
                            display_status: "admin_broadcast",
                            notification_type: "CHAT",
                            title: "New message from " + senderName,
                            body: message,
                            group_path: groupPath,
                            sender_path: senderPath,
                            sender_photo_url: senderPhoto,
                            chat_id: chatId
                        }
                    };

                    console.log("Sending notification");
                    return admin.messaging().sendToDevice(tokens, payload);
                });
            });
        });
    });
});

Then I ran (It does not let me run locally because - function ignored because the firestore emulator does not exist or is not running.):

firebase deploy --only functions

In android I implemented the following class:

public class MessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        Log.d(TAG, "onMessageReceived: started");
        Log.d(TAG, "onMessageReceived: message is: " + remoteMessage.getData());
        // code
    }

    @Override
    public void onNewToken(@NonNull String token) {
        Log.d(TAG, "Refreshed user token: " + token);
        sendRegistrationToServer(token);
    }

    // code
}

But in the log section of the functions tab of the firebase console I get the following error:

onMessageSent
Error: Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string.
    at Object.validateResourcePath (/srv/node_modules/@google-cloud/firestore/build/src/path.js:406:15)
    at Firestore.doc (/srv/node_modules/@google-cloud/firestore/build/src/index.js:427:16)
    at exports.onMessageSent.db.document.onCreate (/srv/index.js:19:30)
    at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:132:23)
    at /worker/worker.js:825:24
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7) 

What does it mean and how to fix it?

Upvotes: 0

Views: 3139

Answers (1)

blay
blay

Reputation: 464

It's mean that you try get document. but the path isn't String. If you look in error you see that happen in line 30. I think that admin.firestore().doc(userPath) is the problem. userPath is object and don't string. try to convert toString()

Upvotes: 2

Related Questions