从PubNub获取未读消息并呈现通知



我正在尝试从PubNub获取未读消息。流程如下:

  1. 设置权限
  2. 获取通道元数据
  3. 获取未读消息等

我不能按顺序运行这些函数。

async function setGrant(){
await pubnub.grant(
{
channels: [userId.toString() + '.*'],
ttl: 55,
read: true,
write: true,
update: true,
get: true,
},(status) => {
return new Promise(function (resolve) {
resolve(status)
});
});
}
async function getMetadata() {
await pubnub.objects.getAllChannelMetadata(
{
include: {
customFields: true
}
}).then((res: any) => {
return new Promise(function (resolve) {
resolve(setChannelMetadata(res.data));
});
});
}

async function getUnreadedMessages() {
await pubnub.messageCounts({
channels: channels,
channelTimetokens: tokens,
}).then((res: any) => {
console.log(res);
return new Promise(function (resolve) {
resolve(setUnreadMessage(res));
});
});
}

async function setChannelsAndTokens(){
channelMetadata.forEach((value, index) => {
tokens.push(value.custom.lastToken);
channels.push(value.id)
});
return new Promise(function (resolve) {
getUnreadedMessages()
resolve("Chanells and tokens set!");
})
}
function getUnreadMessagesProccess() {
return setGrant().then(getMetadata).then(setChannelsAndTokens).then(getUnreadedMessages)
}

编辑:

看起来这也是渲染的问题。当我得到getUnreadedMessages()然后我正在编辑对象客户端:

clients.forEach((value, index) => {
if (res.channels[value.id + '-' + userId + '-chat']) {
value.unreadMessages = res["channels"][value.id + '-' + userId + '-chat'];
} else {
value.unreadMessages = 0;
}
console.log("UNREAD MESSAGE", value.unreadMessages, value.username);
});

基于此,我正在设置showIcon:

<ClientItem
client={item.item}
isAdmin={isAdmin}
navigation={navigation}
fromAdminTab={fromAdminTab}
showIcon={item.item.unreadMessages>0}
/>

但是这个图标没有正确显示。

ClientList:

import Colors from '@helper/Colors';
import { useSelector } from '@redux/index';
import { HealthierLifeOption } from '@redux/types';
import React, { useEffect, useState } from 'react';
import { View, Text, FlatList, ActivityIndicator } from 'react-native';
import ClientItem from './ClientItem';
import {usePubNub} from "pubnub-react";

export type Client = {
id: number;
username: string;
individualPlanPaid: boolean;
healthierLifeOption?: HealthierLifeOption;
company?: {
id: number;
companyName: string;
};
mentor?: {
id: number;
username: string;
};
}

type Props = {
navigation: any;
clients: Client[];
isAdmin?: boolean;
isLoading: boolean;
onEndReached: Function;
fromAdminTab?: boolean
}

const ClientList = ({ navigation, clients, onEndReached, isLoading, isAdmin = false, fromAdminTab= false }: Props) => {
const resultCount = useSelector(state => state.user.menteesResultCount);
const [hasMoreResults, setHasMoreResults] = useState(true);
const userId = useSelector(state => state.user.id);
const pubnub = usePubNub();

useEffect(() => {

getUnreadMessagesProccess
setHasMoreResults(resultCount !== clients?.length);

}, [resultCount, clients]);


async function setGrant() {
return new Promise( async resolve => {
await pubnub.grant({
channels: [
'100-68-chat',
'101-68-chat',
'22-2-chat',
'22-96-chat',
'73-68-chat',
'78-68-chat',
'79-68-chat',
'81-68-chat',
'90-68-chat',
'92-68-chat',
'93-68-chat',
'98-68-chat',
'99-68-chat' ],
ttl: 55,
read: true,
write: true,
update: true,
get: true,
}, response => resolve(response));
});
}

async function getMetadata() {
const options = {include: {customFields: true}};
return await pubnub.objects.getAllChannelMetadata(options);
}

function setChannelsAndTokens(channelMetadata, channels, tokens) {

channelMetadata.data.forEach((value, index) => {
tokens.push(value.custom.lastToken);
channels.push(value.id.toString())
});
}

async function getUnreadedMessages(channels, tokens) {
return new Promise(async resolve => {
pubnub.messageCounts({
channels: null,
channelTimetokens: tokens,
}).then(res => {
clients.forEach((value, index) => {
if (res.channels[value.id + '-' + userId + '-chat']) {
value.unreadMessages = res["channels"][value.id + '-' + userId + '-chat'];
} else {
value.unreadMessages = 0;
}
console.log("UNREAD MESSAGE", value.unreadMessages, value.username);
});
resolve()
})
.catch(error => resolve(error));
});
}

async function getUnreadMessagesProccess() {
const tokens = ['1000'];
const channels = ['1234567'];
const userId = 1234567;

const auth = await setGrant(userId);
log([{statusCode: auth.statusCode}]);

const channelMetadata = await getMetadata();
log([channelMetadata,channels,tokens]);

setChannelsAndTokens(channelMetadata, channels, tokens);
const unread = await getUnreadedMessages(channels, tokens);
log([unread]);

return unread;
}


return (
<View>
<FlatList
keyExtractor={item => item.id.toString()}
data={clients}
onEndReached={() => hasMoreResults ? onEndReached() : null}
onEndReachedThreshold={0.4}
renderItem={item => (
<ClientItem
client={item.item}
isAdmin={isAdmin}
navigation={navigation}
fromAdminTab={fromAdminTab}
showIcon={parseInt(item.item.unreadMessages) > 0 }
/>
)}
ListFooterComponent={isLoading
? () => (
<View style={{ padding: 20 }}>
<ActivityIndicator animating size="large" color={Colors.border_gray} />
</View>
)
: null
}
/>
</View>
);
}
export default ClientList;

ClientItem:

import React, {useEffect, useState} from 'react';
import { Text, View, Image, TouchableOpacity } from 'react-native';
import Images from '@helper/Images';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import Colors from '@helper/Colors';
import styles from '../styles';
import ClientModal from './ClientModal/ClientModal';
import { Client } from './ClientList';
import { HealthierLifeOption } from '@redux/types';

type Props = {
client: Client;
navigation: any;
isAdmin?: boolean;
fromAdminTab?: boolean;
showIcon?: boolean
}

const ClientItem = ({ client, navigation, isAdmin = false, fromAdminTab= false, showIcon= false }: Props) => {
const [showModal, setShowModal] = useState(false);

console.log(showIcon); // its not passed correclty

let clientIcon = Images.icon.logoIconOrange 

const handleContinueButton = () => {
if(!fromAdminTab) {
navigation.navigate('ChatFromClientsList', { selectedId: client.id, showBackButton: true });
}else {
setShowModal(!showModal)
}
};

return (
<View style={styles.client_item_container}>

<TouchableOpacity style={styles.client_content_container} onPress={handleContinueButton}
>
<View style={styles.image_container}>
<Image
style={styles.client_profile_img}
source={clientIcon}
resizeMode="contain"
resizeMethod="resize"
/>
</View>
<View style={styles.title_container}>
<Text style={styles.title} >{ client.username } </Text>
</View>
<View style={styles.dot_container}>
{showIcon  &&  <FontAwesome5
name="comment-dots"
size={20}
color={Colors.red}
/>  }
</View>
<View style={styles.hamburger_container} >
<FontAwesome5
name="bars"
size={30}
color={Colors.black}
onPress={() => setShowModal(!showModal)}
/>
</View>
<View>
<ClientModal
isVisible={showModal}
onCollapse={(value: boolean) => setShowModal(value)}
closeModal={(value: boolean) => setShowModal(value)}
client={client}
navigation={navigation}
isAdmin={isAdmin}
/>
</View>
</TouchableOpacity>
</View>
);
};
export default ClientItem;

我不确定这是否因为从Pubnub或因为渲染或如何处理数据在foreach中。

在前一个函数完成后运行

以经验编码方式使用asyncawait。这有助于组织代码。使代码易于阅读。这也有助于操作顺序。

我们所做的是在每个函数的awaitpromise前面添加一个return。这允许我们在每个函数完成执行后赋值结果变量,同时在编写代码时保持执行顺序。

💡注意:当使用secretKey初始化SDK时,不需要授予自己对资源的访问权限。只要使用任何方法,就像您已经拥有权限一样。

SDK将自动使用您的密钥对所有请求签名。

Run code snippet测试按钮。

(async ()=>{
'use strict';
const publishKey   = "pub-c-51f1008b-7ddf-42b7-aec9-2d0153b0e766";
const subscribeKey = "sub-c-1597b696-05af-11e6-a6dc-02ee2ddab7fe";
const secretKey    = "sec-c-YTVjYjUzMWMtM2MxZC00YzdiLWE0ZjAtNWRmMWVmYmNkZGNl";
const myUUID       = "myUniqueUUID"
const pubnub = new PubNub({
publishKey   : publishKey,
subscribeKey : subscribeKey,
secretKey    : secretKey,
uuid         : myUUID,
});
const unread = await getUnreadMessagesProccess();
async function getUnreadMessagesProccess() {
const tokens = ['1000'];      // placeholder change me
const channels = ['1234567']; // placeholder change me
const userId = 1234567;       // placeholder change me
const auth = await setGrant(userId);
log([{statusCode: auth.statusCode}]);
const channelMetadata = await getMetadata();
log([channelMetadata,channels,tokens]);
setChannelsAndTokens(channelMetadata, channels, tokens);
const unread = await getUnreadedMessages(channels, tokens);
log([unread]);
return unread;
}
async function setGrant(userId) {
return new Promise( async resolve => {
await pubnub.grant({
channels: [userId.toString() + '.*'],
ttl: 55,
read: true,
write: true,
update: true,
get: true,
}, response => resolve(response));
});
}
async function getMetadata() {
const options = {include: {customFields: true}};
return await pubnub.objects.getAllChannelMetadata(options);
}
function setChannelsAndTokens(channelMetadata, channels, tokens) {
channelMetadata.data.forEach((value, index) => {
tokens.push(value.custom.lastToken);
channels.push(value.id)
});
}
async function getUnreadedMessages(channels, tokens) {
try {
return await pubnub.messageCounts({
channels: channels,
channelTimetokens: tokens,
});
}
catch(error) {
return error;
}
}
async function getUnreadedMessagesAlternative(channels, tokens) {
return new Promise(async resolve => {
pubnub.messageCounts({
channels: channels,
channelTimetokens: tokens,
}).then(result => resolve(result))
.catch(error => resolve(error));
});
}
function log(data) {
// console.log(data);
document.querySelector("#out").innerHTML += 
`<div>${JSON.stringify(data)}</div>`;
}
})();
<div id="out"></div>
<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.33.0.js"></script>

最新更新