如何将用于Firebase云功能的打字稿代码中的快照转换为用于通知的字符串?

时间:2019-05-27 03:29:27

标签: typescript firebase firebase-cloud-messaging google-cloud-functions

我有下面的云功能代码,用于在创建新关注者时向用户发送通知。问题是我不知道如何将快照转换为字符串,这样才能解决以下错误消息。

 function sendNewFollowNotificationFunc(uuid: string, newFollower: string) {
  // const userRef = admin.database().ref('PeopleWhoFollowMe').child(uuid)
  // const fetchAndUpdate = userRef.once('value')
  console.log('User to send notification', uuid);

  admin.database().ref(`UsersFireTokens`).child(uuid).child("token").once('value')
  .then(snap => {
    const token = snap.val//I dont know how, from here I should be handling this inorder to get the value at this location which is the token
    // This registration token comes from the client FCM SDKs.
    var registrationToken = token;

    var message = {
      data: {
        text: 'This is a test',
        time: '2:45'
      },
      token: registrationToken
    };

    // Send a message to the device corresponding to the provided
    // registration token.
    admin.messaging().send(message)//error here
      .then((response) => {
        // Response is a message ID string.
        console.log('Successfully sent message:', response);
      })
      .catch((error) => {
        console.log('Error sending message:', error);
      });
  })
  .catch(error => {
    console.log("Error in catch: "+error)
    response.status(500).send(error)
  })

问题是我遇到很多错误,例如:

  

类型'{数据:{文本:字符串;时间:字符串; };令牌:字符串|空值; }”不可分配给“消息”类型的参数。     输入'{data:{text:string;时间:字符串; };令牌:字符串|空值; }”不可分配给“ TokenMessage”类型。       属性“令牌”的类型不兼容。         输入'string | “ null”不可分配给“ string”类型。           类型'null '不能分配给类型'string'.ts(2345)

我在做什么错了,我该如何解决?

更新:

这是我的代码:

function sendNewFollowNotificationFunc(uuid: string, newFollower: string) {
  // const userRef = admin.database().ref('PeopleWhoFollowMe').child(uuid)
  // const fetchAndUpdate = userRef.once('value')
  console.log('User to send notification', uuid);

  admin.database().ref(`UsersFireTokens`).child(uuid).child("token").once('value')
  .then(snap => {
    //What should I be doing here and how?
console.log('token value', snap.val);//doing this returns a strange function thing in the logs

  })
  .catch(error => {
    console.log("Error in catch: "+error)
    response.status(500).send(error)
  })
}

1 个答案:

答案 0 :(得分:0)

冗长而复杂的tsc消息告诉您message变量的类型为:

{ data: { text: string; time: string; }; token: string | null; }

但是send期望TokenMessage。无法从代码中完全了解TokenMessage类型,但似乎包含token类型的string字段。另一方面,您的message具有一个token类型的string | null字段。因此,类型不匹配:您的message可能没有token,而send期望可以保证有token字符串。

  

我在做什么错,我该如何解决?

您需要使用一些符合send类型的值来调用TokenMessage

为此,一种方法是将message强制转换为tokenMessage

 admin.messaging().send(message as Message)

tldr:上面的类似内容可能会解决您的问题

有时,两种类型太不兼容而无法转换。在这种情况下,您不能像上一行那样强制使用它。您仍然可以强制转换为any,然后转换为所需的类型:

admin.messaging().send(message as any as Message)


因此,这并不总是您应该做的:

Typescript抱怨message可能没有token。那很整齐。通常,您可以通过对变量进行断言来避免这些tsc警告:

function getToken(): string | null {
    return 'f00';
}

function test(s: string) { 

}

const t = getToken();

test(t); // error

if (t) {
    test(t); // safe, no error
    // this is great because force you to handle potential null stuff at developing time
}

但这似乎不适用于对象字段:

function getToken(): string | null {
    return 'f00';
}

interface Message{
    token: string;
}

function send(m: Message) { 

}

const t = getToken();

const message = {
    token: t,
}

send(message); // error

if (t) {
    send(message); // error
}

if (message.token) { 
    send(message); // still an error, this puzzles me a lot. At this point tsc should now that message complies with Message. There is something I don't have clear at this point.
}

send(message as Message); // valid

通常,通过if块检查空值比手动转换类型更安全。但是有时候别无选择。