question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

PLEASE REPORT: Excessive number of pending callbacks: 501

See original GitHub issue

Description

Hi,

I keep the getting the error seen on the screenshot below. For context, I’m creating an app (IOS) where users can swipe through a number of songs to listen to the audio and comment on each song.

This error warning shows when I finish swiping on a song and load the next one. Any help would be great - my app keeps crashing on my physical device (fine on simulator) after a few swipes. Full error shown below.

Version

0.66.1

Output of npx react-native info

System: OS: macOS 12.3.1 CPU: (8) arm64 Apple M1 Memory: 95.30 MB / 16.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.16.0 - /usr/local/bin/node Yarn: 1.22.19 - /usr/local/bin/yarn npm: 8.11.0 - /usr/local/bin/npm Watchman: 2022.06.27.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.3 - /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5 Android SDK: Not Found IDEs: Android Studio: Not Found Xcode: 13.4/13F17a - /usr/bin/xcodebuild Languages: Java: Not Found npmPackages: @react-native-community/cli: Not Found react: 18.0.0 => 18.0.0 react-native: 0.69.1 => 0.69.1 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

Swipe through songs to reproduce.

Snack, code example, screenshot, or link to a repository

  StyleSheet,
  Text,
  View,
  Dimensions,
  Image,
  TextInput,
  FlatList,
  TouchableOpacity,
  ScrollView,
  Keyboard,
} from 'react-native';
import React, {useState, useEffect, useRef, useMemo, useCallback} from 'react';
import {Gesture, GestureDetector} from 'react-native-gesture-handler';
import {firebase} from '@react-native-firebase/firestore';
import Colors from '../assets/utilities/Colors';
import Spotify from '../assets/img/spotify.svg';
import AsyncStorage from '@react-native-async-storage/async-storage';
import firestore from '@react-native-firebase/firestore';
import storage from '@react-native-firebase/storage';
import Ionicons from 'react-native-vector-icons/Ionicons';
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  withSpring,
  runOnJS,
} from 'react-native-reanimated';
const {height: SCREEN_HEIGHT} = Dimensions.get('window');

const BottomSheet = props => {
  console.log(SCREEN_HEIGHT);
  const caption = props.captionProps;
  const songID = props.songIDProps;
  const navigation = props.navigationProps;
  const [UID, setUID] = useState();
  const [displayName, setDisplayName] = useState();
  const [profilePicURL, setProfilePicURL] = useState();
  const [inputTop, setInputTop] = useState(false);
  const [commentText, setCommentText] = useState();
  const [parentComments, setParentComments] = useState();
  const [activeLikedComments, setActiveLikedComments] = useState([]);
  const [likeChanged, setLikedChanged] = useState(false);
  const [myComment, setMyComment] = useState(false);
  const [bottomSheetSmall, setBottomSheetSmall] = useState(false);
  const [commentID, setCommentID] = useState();
  const inputRef = useRef();
  const replyUsernameRef = useRef();
  const [replyUsername, setReplyUsername] = useState();
  const [replyActive, setReplyActive] = useState(false);
  const [replyID, setReplyID] = useState();
  const [parentReplies, setParentReplies] = useState();
  const [viewReplies, setViewReplies] = useState(false);
  const [containerUp, setContainerUp] = useState(false);
  const translateY = useSharedValue(0);
  const scrollTo = useCallback(
    destination => {
      'worklet';
      translateY.value = withSpring(destination, {damping: 50});
    },
    [translateY],
  );
  const context = useSharedValue({y: 0});

  const gesture = Gesture.Pan()
    .onStart(() => {
      context.value = {y: translateY.value};
    })
    .onUpdate(event => {
      translateY.value = event.translationY + context.value.y;
      translateY.value = Math.max(translateY.value, -269);
    })
    .onEnd(() => {
      if (!containerUp) {
        if (translateY.value <= -50) {
          scrollTo(-269);
          runOnJS(setContainerUp)(true);
        } else if (translateY.value >= 50) {
          scrollTo(100);
        } else {
          scrollTo(0);
        }
        runOnJS(setBottomSheetSmall)(true);
      } else if (containerUp) {
        if (translateY.value >= -240) {
          scrollTo(0);
          runOnJS(setContainerUp)(false);
        } else {
          scrollTo(0);
        }
        runOnJS(setBottomSheetSmall)(false);
      }
    });

  const rBottomSheetStyle = useAnimatedStyle(() => {
    return {
      transform: [{translateY: translateY.value}],
    };
  });

  useEffect(() => {
    const checkforUID = async () => {
      const userUID = await AsyncStorage.getItem('UID');
      if (userUID) {
        console.log(userUID);
        setUID(userUID);
      }
    };
    checkforUID();
  }, []);

  useEffect(() => {
    if (UID) {
      const getProfilePicURL = async () => {
        const url = await storage()
          .ref(UID + 'PFP')
          .getDownloadURL()
          .catch(error => {
            console.log(error);
            const getDefaultPicURL = async () => {
              const defaultURL = await storage()
                .ref('circle.png')
                .getDownloadURL()
                .catch(error2 => {
                  console.log(error2);
                });
              setProfilePicURL(defaultURL);
              console.log(url);
            };
            getDefaultPicURL();
          });
        setProfilePicURL(url);
        console.log(url);
      };
      getProfilePicURL();

      const getUserProfile = async () => {
        const user = await firestore().collection('users').doc(UID).get();
        setDisplayName(user._data?.displayName);
      };
      getUserProfile();
    }
  }, [UID]);

  useEffect(() => {
    if (UID) {
      const getUserProfile = async () => {
        const user = await firestore().collection('users').doc(UID).get();
        setDisplayName(user._data?.displayName);
      };
      getUserProfile();
    }
  }, [UID]);

  useEffect(() => {
    if (displayName) {
      console.log(displayName);
    }
  }, [displayName]);

  const postComment = () => {
    const currentdate = new Date();
    firestore()
      .collection('posts')
      .doc(songID)
      .collection('comments')
      .add({
        UID: UID,
        parent: 'none',
        comment: commentText,
        profilePicURL: profilePicURL,
        displayName: displayName,
        likeAmount: 0,
        hasReplies: 'no',
        commentAddedAt:
          currentdate.getMonth() +
          1 +
          '/' +
          currentdate.getUTCDate() +
          '/' +
          currentdate.getFullYear() +
          ' @ ' +
          currentdate.getHours() +
          ':' +
          currentdate.getMinutes() +
          ':' +
          currentdate.getSeconds(),
      })
      .then(() => {
        console.log('post added!');
      });
  };

  // get all parent comments
  useEffect(() => {
    if (songID) {
      firestore()
        .collection('posts')
        .doc(songID)
        .collection('comments')
        .where('parent', '==', 'none')
        .orderBy('likeAmount', 'desc')
        .get()
        .then(querySnapshot => {
          console.log(querySnapshot);
          setParentComments(querySnapshot._docs);
        });
      //re-run this effect everytime a user posts a comment
      setMyComment(false);
    }
  }, [songID, myComment]);

  // useEffect(() => {
  //   if (songID) {
  //     firestore()
  //       .collection('posts')
  //       .doc(songID)
  //       .collection('comments')
  //       .doc('ttttttttttttttttttttttt')
  //       .get()
  //       .then(querySnapshot => {
  //         console.log(querySnapshot);
  //         setParentComments(querySnapshot._docs);
  //       });
  //     //re-run this effect everytime a user posts a comment
  //     setMyComment(false);
  //   }
  // }, []);

  // Like a comment logic
  useEffect(() => {
    const increment = firebase.firestore.FieldValue.increment(1);
    const minusIncrement = firebase.firestore.FieldValue.increment(-1);
    if (commentID) {
      if (activeLikedComments.includes(commentID)) {
        setActiveLikedComments(
          activeLikedComments.filter(comment => comment !== commentID),
        );
        firestore()
          .collection('posts')
          .doc(songID)
          .collection('comments')
          .doc(commentID)
          .update({
            likeAmount: minusIncrement,
          });
      } else {
        setActiveLikedComments(current => [...current, commentID]);
        try {
          firestore()
            .collection('posts')
            .doc(songID)
            .collection('comments')
            .doc(commentID)
            .update({
              likeAmount: increment,
            });
        } catch (error) {
          console.log(error);
        }
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [likeChanged, commentID]);

  useEffect(() => {
    if (activeLikedComments) {
      console.log(activeLikedComments);
    }
  }, [activeLikedComments]);

  // REPLY LOGIC BELOW
  const postReply = () => {
    const currentdate = new Date();
    firestore()
      .collection('posts')
      .doc(songID)
      .collection('comments')
      .add({
        UID: UID,
        parent: replyID,
        comment: commentText,
        profilePicURL: profilePicURL,
        displayName: displayName,
        likeAmount: 0,
        commentAddedAt:
          currentdate.getMonth() +
          1 +
          '/' +
          currentdate.getUTCDate() +
          '/' +
          currentdate.getFullYear() +
          ' @ ' +
          currentdate.getHours() +
          ':' +
          currentdate.getMinutes() +
          ':' +
          currentdate.getSeconds(),
      })
      .then(() => {
        console.log('post added!');
      });
    firestore()
      .collection('posts')
      .doc(songID)
      .collection('comments')
      .doc(replyID)
      .update({
        hasReplies: 'yes',
      })
      .then(() => {
        console.log('post added!');
      });
  };

  const commentHandler = () => {
    if (replyActive) {
      postReply();
      console.log('reply is true');
      setReplyActive(false);
    } else {
      postComment();
    }
  };

  useEffect(() => {
    if (replyID) {
      firestore()
        .collection('posts')
        .doc(songID)
        .collection('comments')
        .where('parent', '==', replyID)
        .orderBy('likeAmount', 'desc')
        .get()
        .then(querySnapshot => {
          console.log(querySnapshot);
          setParentReplies(querySnapshot);
        });
      //re-run this effect everytime a user posts a comment
      setMyComment(false);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [viewReplies, myComment]);

  useEffect(() => {
    if (parentReplies) {
      console.log(parentReplies?._docs[0]?._data?.parent);
    } else {
      console.log('not true');
    }
  }, [parentReplies]);

  return (
    <>
      <GestureDetector gesture={gesture}>
        <Animated.View
          style={[styles.commentContainerBackground, rBottomSheetStyle]}>
          <View style={styles.drawer} />
          {caption && (
            <View style={styles.captionContainer}>
              <View style={styles.userContainer}>
                <Spotify height={15} width={15} />
                <Text style={styles.username}>username</Text>
              </View>
              <View style={styles.captionTextContainer}>
                <Text style={styles.caption}>{caption}</Text>
              </View>
            </View>
          )}

          {parentComments && (
            <FlatList
              // style={styles.commentFlatList}
              // contentContainerStyle={{paddingBottom: '200%'}}
              contentContainerStyle={
                bottomSheetSmall
                  ? {paddingBottom: '110%'}
                  : {paddingBottom: '160%'}
              }
              data={parentComments}
              renderItem={({item, index}) => {
                return (
                  <>
                    <View key={index} style={styles.mainContainer}>
                      <View style={styles.commentContainer}>
                        <View style={styles.commentLeftSide}>
                          <TouchableOpacity
                            onPress={() =>
                              navigation.navigate('ViewUserScreen', {
                                UID: item._data.UID,
                                myUID: UID,
                              })
                            }>
                            <Image
                              style={styles.userProfilePic}
                              source={{
                                uri: item._data.profilePicURL,
                              }}
                            />
                          </TouchableOpacity>
                          <View style={styles.commentTextContainer}>
                            <TouchableOpacity
                              onPress={() =>
                                navigation.navigate('ViewUserScreen', {
                                  UID: item._data.UID,
                                  myUID: UID,
                                })
                              }>
                              <Text
                                ref={replyUsernameRef}
                                style={styles.userDisplayName}>
                                {item._data.displayName}
                              </Text>
                            </TouchableOpacity>
                            <Text style={styles.userComment}>
                              {item._data.comment}
                            </Text>
                          </View>
                        </View>
                        <View style={styles.likesContainer}>
                          <TouchableOpacity
                            onPress={() => {
                              setCommentID(item.id);
                              setMyComment(!myComment);
                              setLikedChanged(!likeChanged);
                            }}>
                            <Ionicons
                              style={styles.socialIcon}
                              name={
                                activeLikedComments.includes(item.id)
                                  ? 'heart'
                                  : 'heart-outline'
                              }
                              color={
                                activeLikedComments.includes(item.id)
                                  ? Colors.red
                                  : 'grey'
                              }
                              size={18}
                            />
                          </TouchableOpacity>
                          <Text style={styles.likeText}>
                            {item._data.likeAmount}
                          </Text>
                        </View>
                      </View>
                      <TouchableOpacity
                        onPress={() => {
                          setReplyActive(!replyActive);
                          inputRef.current.focus();
                          setReplyUsername(item._data.displayName);
                          setReplyID(item.id);
                        }}
                        style={styles.replyContainer}>
                        <Text style={styles.replyText}>Reply</Text>
                      </TouchableOpacity>
                      {item._data.hasReplies === 'yes' && (
                        <TouchableOpacity
                          style={styles.viewRepliesContainer}
                          onPress={() => {
                            setReplyID(item.id);
                            setViewReplies(!viewReplies);
                          }}>
                          <Text style={styles.viewRepliesText}>
                            View Replies
                          </Text>
                          <Ionicons
                            // style={styles.socialIcon}
                            name={viewReplies ? 'chevron-up' : 'chevron-down'}
                            color={'grey'}
                            size={18}
                          />
                        </TouchableOpacity>
                      )}
                      {parentReplies &&
                      item.id === parentReplies._docs[0]._data?.parent &&
                      viewReplies ? (
                        <>
                          {parentReplies._docs.map(reply => {
                            return (
                              <View
                                key={reply._data.id}
                                style={styles.repliesContainer}>
                                <View style={styles.repliesLeftSide}>
                                  <Image
                                    style={styles.repliesProfilePic}
                                    source={{
                                      uri: reply._data.profilePicURL,
                                    }}
                                  />
                                  <View style={styles.repliesTextContainer}>
                                    <Text
                                      ref={replyUsernameRef}
                                      style={styles.repliesDisplayName}>
                                      {reply._data.displayName}
                                    </Text>
                                    <Text style={styles.repliesComment}>
                                      {reply._data.comment}
                                    </Text>
                                  </View>
                                </View>
                                <View style={styles.likesContainer}>
                                  <TouchableOpacity
                                    onPress={() => {
                                      setCommentID(reply.id);
                                      setMyComment(!myComment);
                                      setLikedChanged(!likeChanged);
                                    }}>
                                    <Ionicons
                                      style={styles.socialIcon}
                                      name={
                                        activeLikedComments.includes(reply.id)
                                          ? 'heart'
                                          : 'heart-outline'
                                      }
                                      color={
                                        activeLikedComments.includes(reply.id)
                                          ? Colors.red
                                          : 'grey'
                                      }
                                      size={18}
                                    />
                                  </TouchableOpacity>
                                  <Text style={styles.likeText}>
                                    {reply._data.likeAmount}
                                  </Text>
                                </View>
                              </View>
                            );
                          })}
                        </>
                      ) : null}
                    </View>
                  </>
                );
              }}
            />
          )}

Simulator Screen Shot - iPhone 13 - 2022-08-17 at 17 38 14

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

7reactions
mjmasncommented, Nov 9, 2022

Yeah this seems to be caused by a change to TouchableOpacity in React Native 0.69…

https://github.com/facebook/react-native/commit/3eddc9abb70eb54209c68aab7dbd69e363cc7b29

(flattenStyle(prevProps.style)?.opacity !==
        flattenStyle(this.props.style)?.opacity) !==
        undefined

is always going to evaluate to true, therefore calling this._opacityInactive(250); as many times as the component is (re)rendered.

Quick fix: remove the !== undefined from node_modules/react-native/Libraries/Components/Touchable/TouchableOpacity.js then run npx patch-package react-native

7reactions
treykapfercommented, Sep 20, 2022

I just ran into this same issue. I tracked it down to the TouchableOpacities in a few components and replaced them with Pressables, and that got rid of the error. I think the “NativeAnimatedModule” is referring to the animation on the touchableOpacity components

Read more comments on GitHub >

github_iconTop Results From Across the Web

Excessive number of pending callbacks: 501 #27483 - GitHub
This issue is occuring because you are using useEffect in many functions to check for every change in state. Reduce this number and...
Read more >
How to avoid "Excessive number of pending callbacks
How to avoid "Excessive number of pending callbacks: 501" error during images download in React Native? Ask Question. Asked 2 years, 8 months ......
Read more >
501” error during images download in React Native – iTecNote
Excessive number of pending callbacks : 501. Is there a better way of doing the same thing, so that the error does not...
Read more >
Excessive number of pending callbacks - appsloveworld
Coding example for the question Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked-React Native.
Read more >
react-native-track-player/Support - Gitter
Warning: Please report: Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked by never being called from native code: ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found