iOS Development

javascript – Unable to get a sound Expo push token

Spread the love


I am engaged on a React Native app with Expo. I am struggling to get a sound token and due to this fact, the push notifications aren’t working.

Every time I paste the acquired token on https://expo.dev/notifications, I get an error message that claims “This isn’t a sound Expo push token.”. The notifications work on Expo Go however not on TestFlight.

That is my code:

import * as System from "expo-device";
import * as Notifications from "expo-notifications";
import React, { useEffect, useRef, useState } from "react";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Ionicons } from "@expo/vector-icons";

import ChatSettingsScreen from "../screens/ChatSettingsScreen";
import SettingsScreen from "../screens/SettingsScreen";
import ChatListScreen from "../screens/ChatListScreen";
import ChatScreen from "../screens/ChatScreen";
import NewChatScreen from "../screens/NewChatScreen";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { useDispatch, useSelector } from "react-redux";
import { getFirebaseApp } from "../utils/firebaseHelper";
import { baby, get, getDatabase, off, onValue, ref } from "firebase/database";
import { setChatsData } from "../retailer/chatSlice";
import {
  ActivityIndicator,
  Alert,
  KeyboardAvoidingView,
  Platform,
  SafeAreaView,
  StyleSheet,
  Textual content,
  View,
} from "react-native";
import colours from "../constants/colours";
import commonStyles from "../constants/commonStyles";
import { setStoredUsers } from "../retailer/userSlice";
import { setChatMessages, setStarredMessages } from "../retailer/messagesSlice";
import ContactScreen from "../screens/ContactScreen";
import DataListScreen from "../screens/DataListScreen";
import { StackActions, useNavigation } from "@react-navigation/native";
import JobApplicationScreen from "../screens/JobApplicationScreen";
import OpportunitiesScreen from "../screens/OpportunitiesScreen";

// Group imports
import CommunityScreen from "../screens/CommunityScreen/CommunityScreen";
import FeedDetailScreen from "../screens/FeedDetailScreen/FeedsDetailScreen";
import NewFeedScreen from "../screens/NewFeedScreen/NewFeedScreen";
import EditFeedScreen from "../screens/EditFeedScreen/EditFeedScreen";
import LocalOpportunityScreen from "../screens/LocalOpportunityScreen";
import axios from "axios";

const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();

const TabNavigator = () => {
  return (
    <Tab.Navigator
      screenOptions={{
        headerShown: false,
      }}
    >
      <Tab.Display
        title="ChatList"
        part={ChatListScreen}
        choices={{
          tabBarLabel: "Chats",
          tabBarIcon: ({ centered }) => (
            <View
              type={
                centered ? Kinds.activeIconBackground : Kinds.iconBackground
              }
            >
              <Ionicons
                title={centered ? "md-chatbubbles" : "md-chatbubbles-outline"}
                measurement={20}
                coloration="#333"
              />
            </View>
          ),
          tabBarActiveTintColor: "#383838",
          tabBarInactiveTintColor: "#383838",
          tabBarLabelStyle: {
            fontSize: 13,
            fontWeight: "600",
          },
        }}
      />
      <Tab.Display
        title="OpportunitiesScreen"
        choices={{
          tabBarLabel: "Alternatives",
          tabBarIcon: ({ centered }) => (
            <View
              type={
                centered ? Kinds.activeIconBackground : Kinds.iconBackground
              }
            >
              <Ionicons
                title={centered ? "md-briefcase" : "md-briefcase-outline"}
                measurement={20}
                coloration="#333"
              />
            </View>
          ),
          tabBarActiveTintColor: "#333",
          tabBarInactiveTintColor: "#333",
          tabBarLabelStyle: {
            fontSize: 13,
            fontWeight: "600",
          },
        }}
        part={OpportunitiesScreen}
      />

      <Tab.Display
        title="CommunityScreen"
        screenOptions={{ headerShown: false }}
        choices={{
          tabBarLabel: "Group",
          tabBarIcon: ({ centered }) => (
            <View
              type={
                centered ? Kinds.activeIconBackground : Kinds.iconBackground
              }
            >
              <Ionicons
                title={centered ? "people-sharp" : "md-people-outline"}
                measurement={20}
                coloration="#333"
              />
            </View>
          ),
          tabBarActiveTintColor: "#383838",
          tabBarInactiveTintColor: "#383838",
          tabBarLabelStyle: {
            fontSize: 13,
            fontWeight: "600",
          },
        }}
        part={CommunityScreen}
      />
    </Tab.Navigator>
  );
};

const StackNavigator = () => {
  return (
    <Stack.Navigator screenOptions={{ headerShown: false }}>
      <Stack.Group>
        <Stack.Display
          title="Residence"
          part={TabNavigator}
          choices={{ headerShown: false }}
        />
        <Stack.Display title="ChatScreen" part={ChatScreen} />
        <Stack.Display
          title="ChatSettings"
          part={ChatSettingsScreen}
          choices={{
            headerTitle: "",
            headerBackTitle: "Again",
            headerShadowVisible: false,
          }}
        />

        <Stack.Display title="JobApplication" part={JobApplicationScreen} />
        <Stack.Display
          title="LocalOpportunity"
          part={LocalOpportunityScreen}
        />

        <Stack.Display title="FeedDetail" part={FeedDetailScreen} />
        <Stack.Display title="NewFeedScreen" part={NewFeedScreen} />
        <Stack.Display title="EditFeedScreen" part={EditFeedScreen} />
        <Stack.Display title="Settings" part={SettingsScreen} />
        <Stack.Display
          title="Contact"
          part={ContactScreen}
          choices={{
            headerTitle: "Contact data",
            headerBackTitle: "Again",
          }}
        />
        <Stack.Display
          title="DataList"
          part={DataListScreen}
          choices={{
            headerTitle: "",
            headerBackTitle: "Again",
          }}
        />
      </Stack.Group>

      <Stack.Group screenOptions={{ presentation: "containedModal" }}>
        <Stack.Display title="NewChat" part={NewChatScreen} />
      </Stack.Group>
    </Stack.Navigator>
  );
};

const MainNavigator = (props) => {
  const dispatch = useDispatch();
  const navigation = useNavigation();

  const [isLoading, setIsLoading] = useState(true);

  const userData = useSelector((state) => state.auth.userData);
  const storedUsers = useSelector((state) => state.customers.storedUsers);

  const [expoPushToken, setExpoPushToken] = useState("");
  console.log("EXPO TOKEN", expoPushToken);
  const notificationListener = useRef();
  const responseListener = useRef();

  useEffect(() => {
    const registerForPushNotifications = async () => {
      strive {
        if (Platform.OS === "android") {
          await Notifications.setNotificationChannelAsync("default", {
            title: "default",
            significance: Notifications.AndroidImportance.MAX,
            vibrationPattern: [0, 250, 250, 250],
            lightColor: "#FF231F7C",
          });
        }

        const { standing: existingStatus } = await Notifications.getPermissionsAsync();
        let finalStatus = existingStatus;

        if (existingStatus !== 'granted') {
          const { standing } = await Notifications.requestPermissionsAsync();
          finalStatus = standing;
        }

        if (finalStatus !== 'granted') {
          console.log('Didn't get push token for push notification!');
          return;
        }

        const token = (await Notifications.getExpoPushTokenAsync({ projectId: '####' })).knowledge;
        console.log('Expo push token:', token);

        // Ship the push token to your server or carry out different obligatory actions
        // For instance:
        // axios.publish("YOUR_SERVER_ENDPOINT", { token });

        setExpoPushToken(token);
      } catch (error) {
        console.error('Error registering for push notifications:', error);
      }
    };

    registerForPushNotifications();

    notificationListener.present = Notifications.addNotificationReceivedListener((notification) => {
      // Deal with acquired notification
    });

    responseListener.present = Notifications.addNotificationResponseReceivedListener((response) => {
      const { knowledge } = response.notification.request.content material;
      const chatId = knowledge["chatId"];

      if (chatId) {
        const pushAction = StackActions.push("ChatScreen", { chatId });
        navigation.dispatch(pushAction);
      } else {
        console.log("No chat id despatched with notification");
      }
    });

    return () => {
      Notifications.removeNotificationSubscription(notificationListener.present);
      Notifications.removeNotificationSubscription(responseListener.present);
    };
  }, []);

  useEffect(() => {
    if (expoPushToken) {
      // Subscribe to push notifications in your server
      strive {
        const response = axios.publish(
          "https://admin.pandatv.co.za/api/exponent/units/subscribe",
          { token: expoPushToken },
          { headers: { "Content material-Kind": "software/json" } }
        );

        console.log("Efficiently subscribed:", response.knowledge);
      } catch (error) {
        console.error("Error whereas subscribing:", error);
      }
    }
  }, [expoPushToken]);
  
  useEffect(() => {
    console.log("Subscribing to firebase listeners");

    const app = getFirebaseApp();
    const dbRef = ref(getDatabase(app));
    const userChatsRef = baby(dbRef, `userChats/${userData.uid}`);
    const refs = [userChatsRef];

    onValue(userChatsRef, (querySnapshot) => {
      const chatIdsData = querySnapshot.val() || {};
      const chatIds = Object.values(chatIdsData);

      const chatsData = {};
      let chatsFoundCount = 0;

      for (let i = 0; i < chatIds.size; i++) {
        const chatId = chatIds[i];
        const chatRef = baby(dbRef, `chats/${chatId}`);
        refs.push(chatRef);

        onValue(chatRef, (chatSnapshot) => {
          chatsFoundCount++;

          const knowledge = chatSnapshot.val();

          if (knowledge) {
            if (!knowledge.customers.contains(userData.uid)) {
              return;
            }

            knowledge.key = chatSnapshot.key;

            knowledge.customers.forEach((uid) => {
              if (storedUsers[uid]) return;

              const userRef = baby(dbRef, `customers/${uid}`);

              get(userRef).then((userSnapshot) => {
                const userSnapshotData = userSnapshot.val();
                dispatch(setStoredUsers({ newUsers: { userSnapshotData } }));
              });

              refs.push(userRef);
            });

            chatsData[chatSnapshot.key] = knowledge;
          }

          if (chatsFoundCount >= chatIds.size) {
            dispatch(setChatsData({ chatsData }));
            setIsLoading(false);
          }
        });

        const messagesRef = baby(dbRef, `messages/${chatId}`);
        refs.push(messagesRef);

        onValue(messagesRef, (messagesSnapshot) => {
          const messagesData = messagesSnapshot.val();
          dispatch(setChatMessages({ chatId, messagesData }));
        });

        if (chatsFoundCount == 0) {
          setIsLoading(false);
        }
      }
    });

    const userStarredMessagesRef = baby(
      dbRef,
      `userStarredMessages/${userData.uid}`
    );
    refs.push(userStarredMessagesRef);
    onValue(userStarredMessagesRef, (querySnapshot) => {
      const starredMessages = querySnapshot.val() ?? {};
      dispatch(setStarredMessages({ starredMessages }));
    });

    return () => {
      console.log("Unsubscribing firebase listeners");
      refs.forEach((ref) => off(ref));
    };
  }, []);

  if (isLoading) {
    <View type={commonStyles.heart}>
      <ActivityIndicator measurement={"massive"} coloration={colours.major} />
    </View>;
  }

  return (
    <KeyboardAvoidingView
      type={{ flex: 1 }}
      conduct={Platform.OS === "ios" ? "padding" : undefined}
    >
           <SafeAreaView className="flex-1">
           <Textual content> {expoPushToken}</Textual content>
           </SafeAreaView>

      <StackNavigator />
      {/* {Alert.alert("Token", expoPushToken)} */}
    </KeyboardAvoidingView>
  );
};

export default MainNavigator;

const Kinds = StyleSheet.create({
  iconBackground: {
    width: 35,
    peak: 35,
    borderRadius: 20,
    justifyContent: "heart",
    alignItems: "heart",
  },
  activeIconBackground: {
    width: 60,
    peak: 30,
    borderRadius: 20,
    backgroundColor: "#f44f0814",
    justifyContent: "heart",
    alignItems: "heart",
  },
});

async operate registerForPushNotificationsAsync() {
  let token;
  
    if (Platform.OS === 'android') {
      await Notifications.setNotificationChannelAsync('default', {
        title: 'default',
        significance: Notifications.AndroidImportance.MAX,
        vibrationPattern: [0, 250, 250, 250],
        lightColor: '#FF231F7C',
      });
    }
  
    if (System.isDevice) {
      const { standing: existingStatus } = await Notifications.getPermissionsAsync();
      let finalStatus = existingStatus;
  
    if (existingStatus !== 'granted') {
      const { standing } = await Notifications.requestPermissionsAsync();
      finalStatus = standing;
    }

    if (finalStatus !== 'granted') {
      console.log('Didn't get push token for push notification!');
      return;
    }

    strive {
      const response = await Notifications.getExpoPushTokenAsync({ projectId: 'f30216c8-b445-48ed-8771-4677e43fe514' });
      token = response.knowledge;
      console.log('Expo push token:', token);
    } catch (error) {
      console.error('Error getting Expo push token:', error);
    }
    } else {
      console.log('Should use bodily system for Push Notifications');
    }
  
    return token;
  }

Leave a Reply

Your email address will not be published. Required fields are marked *