Ошибка типа: не удается прочитать свойство ‘androidNotificationToken’ неопределенного экспорта.onMessageSent.functions.firestore.document.onCreate(/workspace/index.js

#firebase #flutter #google-cloud-firestore #google-cloud-functions #android-notifications

#firebase #трепетание #google-cloud-firestore #google-cloud-функции #android-уведомления

Вопрос:

ОТРЕДАКТИРОВАНА функция onMessageSent. Все та же ошибка.

Я пытаюсь включить push-уведомления в flutter и использую Firebase Messaging. Я сталкиваюсь со следующей проблемой. Их два, а именно «onCreateActivityFeedItem» и «onMessageSent». Для первого, «onCreateActivityFeedItem», функция уведомления работает отлично, но я не смог распознать проблему со вторым. Пожалуйста, помогите.

Проблема, с которой я сталкиваюсь :

 onMessageSent
TypeError: Cannot read property 'androidNotificationToken' of undefined at exports.onMessageSent.functions.firestore.document.onCreate (/workspace/index.js:152:47) at process._tickCallback (internal/process/next_tick.js:68:7)


  

Вот «onCreateActivityFeedItem» . :
Из моего index.js

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

    // 1) Get user connected to the feed
    const userId = context.params.userId;
    const mediaUrl=context.params.mediaUrl;
    const userRef = admin.firestore().doc(`users/${userId}`);
    const doc = await userRef.get();

    // 2) Once we have user, check if they have a notification token; send notification, if they have a token
    const androidNotificationToken = doc.data().androidNotificationToken;
    const createdActivityFeedItem = snapshot.data();
    if (androidNotificationToken) {
      sendNotification(androidNotificationToken, createdActivityFeedItem);
    } else {
      console.log("No token for user, cannot send notification");
    }

    function sendNotification(androidNotificationToken, activityFeedItem) {
      let body;

      // 3) switch body value based off of notification type
      switch (activityFeedItem.type) {
        case "comment":
          body = `${activityFeedItem.username} replied: ${
            activityFeedItem.commentData
          }.`;
          break;
        case "like":
          body = `${activityFeedItem.username} booped you.`;
          break;
        case "follow":
          body = `${activityFeedItem.username} started petting you.`;
          break;
        default:
          break;
      }

      // 4) Create message for push notification
      const message = {
        notification: {
         body:body,
         image:mediaUrl
         },
        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);
          return null;
        })
         .catch(error => {
         console.log("Successfully sent message", response);
         throw Error("Could not send message.",error)});
//         admin.messaging().sendToDevice(androidNotificationToken,message);
    }
  });
  

Из моего index.js

Вот, «onMessageSent»:

 exports.onMessageSent = functions.firestore
.document('/messages/{chatId}/messageInfo/{messageFeedItem}')
.onCreate(async (snapshot, context) => {
  console.log("Message Created", snapshot.data());

  // 1) Get user connected to the feed
  const chatId=context.params.chatId;
  const userId = context.params.idTo;
  const idTo =context.params.idTo;
  const userRef = admin.firestore().doc(`users/${idTo}`);
  const doc = await userRef.get();
  const createdMessageFeedItem = snapshot.data();
      // 2) Once we have user, check if they have a notification token; send notification, if they have a token
  const androidNotificationToken = doc.data().androidNotificationToken;


  if (androidNotificationToken) {
    sendNotification(androidNotificationToken, createdMessageFeedItem);
  } else {
    console.log("No token for user, cannot send notification");
  }

  function sendNotification(androidNotificationToken,createdMessageFeedItem) {
    let body;

    // 3) switch body value based off of notification type
    switch (messageFeedItem.type) {
      case 0:
        body = `${messageFeedItem.username} has sent a message : ${
          messageFeedItem.content
        }.`;
        break;
      case 1:
        body = `${messageFeedItem.username} has sent an image.`;
        break;
      case 2:
        body = `${messageFeedItem.username} has sent a gif.`;
        break;
      default:
        break;
    }

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

    // 5) Send message with admin.messaging()
    admin
      .messaging()
      .send(androidNotificationToken,message)
      .then(response => {
        // Response is a message ID string
        console.log("Successfully sent message", response);
        return null;
      })
       .catch(error => {
       console.log("Successfully sent message", response);
       throw Error("Could not send message.",error)});
//         admin.messaging().sendToDevice(androidNotificationToken,message);
  }
});
  

Где я вызвал / объявил onMessage, onResume :

 configurePushNotifications() {
    final GoogleSignInAccount user = googleSignIn.currentUser;
    if (Platform.isIOS) {
      getiOSPermission();
    }
    _firebaseMessaging.getToken().then((token) {
      print("Firebase messaging token : $token");
      setState(() {
        currentUser.androidNotificationToken = token;
      });
      usersref.doc(user.id).update({"androidNotificationToken": token});
    });
    _firebaseMessaging.configure(
      onLaunch: (Map<String, dynamic> message) async {
        _firebaseMessaging.getToken().then((token) {
          print("Firebase messaging token : $token");
          usersref.doc(user.id).update({"androidNotificationToken": token});
        });
//        print("On Launch : $messagen");
//        _navigateToDetail(message);
      },
      onResume: (Map<String, dynamic> message) async {
        _firebaseMessaging.getToken().then((token) {
          print("Firebase messaging token : $token");
          usersref.doc(user.id).update({"androidNotificationToken": token});
        });
        print("On Resume : $message");
        _navigateToDetail(message);
      },
      onMessage: (Map<String, dynamic> message) async {
        print("On message : $messagen");
        final String recipientId = message['data']['recipient'];
        final String body = message['notification']['body'];
        if (recipientId == user.id) {
          //Notification shown");
          SnackBar snackBar = SnackBar(
            backgroundColor: Colors.blueAccent,
            content: Text(
              body,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.w600,
              ),
            ),
            action: SnackBarAction(
                label: "Go",
                textColor: Colors.black,
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) {
                      return ActivityFeed();
                    }),
                  );
                }),
          );
          _scaffoldKey.currentState.showSnackBar(snackBar);
        }
        //Notifications not shown.");
      },
    );
  }
  

Я пробовал разные способы, такие как получение androidNotificationToken путем обновления в cloud firestore и получения его, но это не сработало.
[Пользователи в облачном Firestore][1]
[1] https://imgur.com/a/u5Df0zD

Я просто новичок, пытаюсь изучать новые вещи. Пожалуйста, помогите. Спасибо, SLN

Комментарии:

1. При переполнении стека не показывайте изображения текста и кода. Скопируйте только соответствующий код в вопрос и отформатируйте его так, чтобы его было легко читать, копировать и искать.

2. Спасибо, г-н Дуг Стивенсон

Ответ №1:

Cannot read type error of undefined ошибка возникает, когда в docu.data().androidNotificationToken

Убедитесь, что ссылка правильная, я предпочитаю использовать этот тип пути для большей ясности let ref = db.collection(‘users’).doc(userID); и т. Д

Вы также можете получить пустой снимок

 var snapshot = await ref.get();
if(snapshot.empty){
 console.log(‘snapshot is empty’);
}

  

Комментарии:

1. Ошибка: значение для аргумента «documentPath» не является допустимым путем к ресурсу. Путь должен быть непустой строкой. . Попробовал: пусть ref = admin.firestore().collection( users ).doc(userId); const userRef = admin.firestore().doc( users/${userId} ); Что может пойти не так..

2. Эта новая ошибка, которую вы получаете, возникает, когда значение в ссылке равно null