首页 > 解决方案 > TypeError:无法读取未定义的exports.onMessageSent.functions.firestore.document.onCreate(/workspace/index.js)的属性'androidNotificationToken'

问题描述

编辑 onMessageSent 函数。还是同样的错误。

我正在尝试在颤振中启用推送通知,并且我正在使用 Firebase 消息传递。我遇到以下问题。有两个,即“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 : $message\n");
//        _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 : $message\n");
        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.");
      },
    );
  }

我尝试了不同的方法,例如通过在云 Firestore 中更新并获取它来获取 androidNotificationToken,但它没有用。[Cloud Firestore 中的用户][1] [1] https://imgur.com/a/u5Df0zD

我只是一个初学者,正在努力学习新东西。请帮忙。谢谢你,SLN

标签: firebasefluttergoogle-cloud-firestoregoogle-cloud-functionsandroid-notifications

解决方案


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’);
}


推荐阅读