Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12201

App Screen freeze and Excessive Number of pending callbacks

$
0
0

After I have selected a place from suggestions and the data is fetched from Firestore collection or the Maps API (based on the search input box), it shows the place details in selected venue details correctly.

However, when I refocus on the search venue input field to retype the query after the selected venue details have been fetched, the screen freezes and I receive this warning:

WARN  Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked by never being called from native code: {"3190":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3193":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3196":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3199":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3202":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3205":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3208":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3211":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3214":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3217":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3220":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3223":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3226":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3229":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3232":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3235":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3238":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3241":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3244":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3247":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3250":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3253":{"module":"UIManager","method":"configureNextLayoutAnimation"},"3256":{"module":"UIManager","method":"configureNextLayoutAnimation"},"...(truncated keys)...":451}

Here is my code:

import React, { useCallback, useState, useReducer, useEffect, useMemo, useContext } from "react";import { View, Text, TextInput, Button, StyleSheet, TouchableOpacity, Modal, Platform, ScrollView, FlatList, Image, ActivityIndicator, Alert, KeyboardAvoidingView } from 'react-native';import RNPickerSelect from 'react-native-picker-select';import Icon from 'react-native-vector-icons/Feather';import { COLORS, FONTS, SIZES, images } from "../../constants";import { useDispatch, useSelector } from 'react-redux';// more imports const CreateTour = ({ navigation, route }) => {  const { currentUser, userData, updateUserData } = useContext(AuthContext);  const { selectedTour, setSelectedTour, tours, setTourDetails, setTours } = useContext(TourContext);  console.log('Current User:', currentUser);  console.log('User Data:', userData);  const { tourData, initialStep } = route.params || {};  const [currentStep, setCurrentStep] = useState(initialStep || 1);// more   const handleSubmit = async () => {    if (!db) return; // Return if db is not initialized yet    setIsSubmitting(true); // Set isSubmitting to true when the form submission starts      // Store selected tour dates in the 'tourDates' subcollection      const tourDatesRef = collection(tourRef, 'tourDates');      // Get the existing tour dates from Firestore  const existingTourDatesSnapshot = await getDocs(tourDatesRef);  const existingTourDates = existingTourDatesSnapshot.docs.map(doc => doc.data().date);  // Delete removed tour dates from Firestore  const removedDates = existingTourDates.filter(date => !selectedDates.some(selectedDate => selectedDate.toISOString().split('T')[0] === date));  for (const removedDate of removedDates) {    const removedDateDoc = existingTourDatesSnapshot.docs.find(doc => doc.data().date === removedDate);    if (removedDateDoc) {      await deleteDoc(removedDateDoc.ref);    }  }      for (let i = 0; i < selectedDates.length; i++) {        const date = selectedDates[i];        const dateString = date.toISOString().split('T')[0];        const dateId = `date${i + 1}`;        const dateRef = doc(tourDatesRef, dateId);        await setDoc(dateRef, {          date: dateString,           event: {      venueDetails: {        venueData: venueDetails[dateString] || {},      },    },  });       // Store event details for the particular date      const eventData = {        venueDetails: {          venueData: {            id: venueDetails[dateString]?.id || '',            name: venueDetails[dateString]?.name || '',            displayName: venueDetails[dateString]?.displayName || '',            formattedAddress: venueDetails[dateString]?.formattedAddress || '',            placeCoverPhotoUrl: venueDetails[dateString]?.placeCoverPhotoUrl || '',            shortFormattedAddress: venueDetails[dateString]?.shortFormattedAddress || '',            adrFormatAddress: venueDetails[dateString]?.adrFormatAddress || '',            addressComponents: venueDetails[dateString]?.addressComponents || '',            location: venueDetails[dateString]?.location || '',            plusCode: venueDetails[dateString]?.plusCode || '',            types: venueDetails[dateString]?.types || [],            viewport: venueDetails[dateString]?.viewport || null,            accessibilityOptions: venueDetails[dateString]?.accessibilityOptions || {},            businessStatus: venueDetails[dateString]?.businessStatus || '',            googleMapsUri: venueDetails[dateString]?.googleMapsUri || '',            iconBackgroundColor: venueDetails[dateString]?.iconBackgroundColor || '',            iconMaskBaseUri: venueDetails[dateString]?.iconMaskBaseUri || '',            primaryType: venueDetails[dateString]?.primaryType || '',            primaryTypeDisplayName: venueDetails[dateString]?.primaryTypeDisplayName || '',            subDestinations: venueDetails[dateString]?.subDestinations || '',            utcOffsetMinutes: venueDetails[dateString]?.utcOffsetMinutes || '',            currentOpeningHours: venueDetails[dateString]?.currentOpeningHours || '',            currentSecondaryOpeningHours: venueDetails[dateString]?.currentSecondaryOpeningHours || '',            internationalPhoneNumber: venueDetails[dateString]?.internationalPhoneNumber || '',            nationalPhoneNumber: venueDetails[dateString]?.nationalPhoneNumber || '',            priceLevel: venueDetails[dateString]?.priceLevel || '',            rating: venueDetails[dateString]?.rating || '',            regularOpeningHours: venueDetails[dateString]?.regularOpeningHours || '',            regularSecondaryOpeningHours: venueDetails[dateString]?.regularSecondaryOpeningHours || '',            userRatingCount: venueDetails[dateString]?.userRatingCount || '',            websiteUri: venueDetails[dateString]?.websiteUri || '',          },        },      };      await setDoc(dateRef, { date: dateString, event: eventData }, { merge: true });        // Update the tours array in the TourContextsetTours(prevTours => {  const updatedTours = prevTours.map(tour => tour.id === updatedTourData.id ? updatedTourData : tour);  return updatedTours;});       // Navigate back to the Dates screen    navigation.navigate('TourManagerDashboard', {      screen: 'Dates',      params: { updatedTour: updatedTourData },    });  } else {    console.error('Updated tour document not found');  }  } catch (error) {    console.error('Error submitting form:', error);  }  setIsSubmitting(false);};      const renderDateTabs = () => {        return (<View style={styles.dateTabsContainer}>            {selectedDates.map((date, index) => (<TouchableOpacity                key={index}                style={[styles.dateTab, selectedDateIndex === index && styles.selectedDateTab]}                onPress={() => setSelectedDateIndex(index)}><Text style={styles.dateTabDay}>{getDayOfWeek(date)}</Text><Text style={styles.dateTabText}>{getDateText(date)}</Text></TouchableOpacity>            ))}</View>        );      };      const fetchSuggestions = async (query) => {        try {          console.log('Fetching suggestions for query:', query);          console.log('Session token:', sessionToken);          // Default latitude and longitude for India          let latitude = 20.593684; // Latitude of India          let longitude = 78.96288; // Longitude of India          // Try to get the user's current location          if (navigator.geolocation) {            const position = await new Promise((resolve, reject) => {              navigator.geolocation.getCurrentPosition(resolve, reject);            });            latitude = position.coords.latitude;            longitude = position.coords.longitude;          }          const response = await fetch('https://places.googleapis.com/v1/places:autocomplete', {            method: 'POST',            headers: {'Content-Type': 'application/json','X-Goog-Api-Key': 'key',            },            body: JSON.stringify({              input: query,              locationBias: {                circle: {                  center: {                    latitude: latitude,                    longitude: longitude,                  },                  radius: 5000,                },              },              sessionToken: sessionToken,            }),          });          const data = await response.json();          console.log('Autocomplete response:', data);          if (data.suggestions && data.suggestions.length > 0) {            setSuggestions(data.suggestions);            console.log('Suggestions set:', data.suggestions);          } else {            setSuggestions([]);            console.log('No suggestions found');          }        } catch (error) {          console.error('Error fetching suggestions:', error);          Alert.alert('Error', 'Failed to fetch suggestions.');        }      };      const handleSearchVenue = useCallback(        debounce((text) => {          setSearchQuery(text);          console.log('Search query changed:', text);          if (text.length > 0) {            fetchSuggestions(text);          } else {            setSuggestions([]);            console.log('Search query is empty, clearing suggestions');          }        }, 1500, { leading: false, trailing: true }),        []      );      useEffect(() => {        const generateSessionToken = () => {          const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {            const r = (Math.random() * 16) | 0;            const v = c === 'x' ? r : (r & 0x3) | 0x8;            return v.toString(16);          });          setSessionToken(uuid);          console.log('Session token generated:', uuid);        };        if (searchQuery) {          generateSessionToken();        } else {          setSessionToken('');        }        return () => {          setSessionToken('');        };      }, [searchQuery]);      const handleVenueSearch = async () => {        if (!db) return; // Return if db is not initialized yet        try {          const placesRef = collection(db, 'Places');          const venueQuery = query(            placesRef,            where('displayName', '>=', venueSearchQuery),            where('displayName', '<=', venueSearchQuery +'\uf8ff'),            limit(5)          );          const venueSnapshot = await getDocs(venueQuery);          if (venueSnapshot.empty) {            setVenueSearchResults([]);          } else {            const venueData = venueSnapshot.docs.map(doc => ({              id: doc.id,              ...doc.data(),            }));            setVenueSearchResults(venueData);          }        } catch (error) {          console.error('Error searching venues:', error);        }      };      const renderDateFields = () => {        const selectedDate = selectedDates[selectedDateIndex];        if (!selectedDate) {          return null; // Return null or a placeholder component when selectedDate is undefined        }        const dateString = selectedDate.toISOString().split('T')[0];        const handleVenueDetailsChange = (field, value) => {          setVenueDetails(prevDetails => ({            ...prevDetails,            [dateString]: {              ...prevDetails[dateString],              [field]: value,            },          }));        };        const handleSelectFirestoreSuggestion = async (venue) => {          setVenueSearchQuery(venue.displayName);          setVenueSearchResults([]);          try {            // Update the venue details with the fetched data            setVenueDetails((prevDetails) => ({              ...prevDetails,              [dateString]: {                id: venue.id || '',                name: venue.name || '',                displayName: venue.displayName || '',                formattedAddress: venue.formattedAddress || '',                shortFormattedAddress: venue.shortFormattedAddress || '',                adrFormatAddress: venue.adrFormatAddress || '',                location: venue.location || null,                plusCode: venue.plusCode || '',                types: venue.types || [],                viewport: venue.viewport || null,                accessibilityOptions: venue.accessibilityOptions || {},                businessStatus: venue.businessStatus || '',                googleMapsUri: venue.googleMapsUri || '',                iconBackgroundColor: venue.iconBackgroundColor || '',                iconMaskBaseUri: venue.iconMaskBaseUri || '',                primaryType: venue.primaryType || '',                primaryTypeDisplayName: venue.primaryTypeDisplayName || '',                subDestinations: venue.subDestinations ? venue.subDestinations.map(destination => destination.name).join(', ') : '',                utcOffsetMinutes: venue.utcOffsetMinutes || '',                currentOpeningHours: venue.currentOpeningHours || '',                currentSecondaryOpeningHours: venue.currentSecondaryOpeningHours || '',                internationalPhoneNumber: venue.internationalPhoneNumber || '',                nationalPhoneNumber: venue.nationalPhoneNumber || '',                priceLevel: venue.priceLevel || '',                rating: venue.rating || '',                regularOpeningHours: venue.regularOpeningHours || '',                regularSecondaryOpeningHours: venue.regularSecondaryOpeningHours || '',                userRatingCount: venue.userRatingCount || '',                websiteUri: venue.websiteUri || '',                placeCoverPhotoUrl: venue.placeCoverPhotoUrl || '',              },            }));          } catch (error) {            console.error('Error fetching venue details:', error);            Alert.alert('Error', 'Failed to fetch venue details.');          }        };        const handleSelectSuggestion = async (suggestion) => {          setSearchQuery(suggestion.placePrediction.text.text);          setSuggestions([]);          try {            const response = await fetch(              `https://places.googleapis.com/v1/places/${suggestion.placePrediction.placeId}?sessionToken=${sessionToken}`,              {                method: 'GET',                headers: {'Content-Type': 'application/json','X-Goog-Api-Key': 'key','X-Goog-FieldMask':'id,name,photos,addressComponents,adrFormatAddress,formattedAddress,location,plusCode,shortFormattedAddress,types,viewport,accessibilityOptions,businessStatus,displayName,googleMapsUri,iconBackgroundColor,iconMaskBaseUri,primaryType,primaryTypeDisplayName,subDestinations,utcOffsetMinutes,currentOpeningHours,currentSecondaryOpeningHours,internationalPhoneNumber,nationalPhoneNumber,priceLevel,rating,regularOpeningHours,regularSecondaryOpeningHours,userRatingCount,websiteUri',                },              }            );            const data = await response.json();            console.log('Place Details:', data);            if (data.error) {              console.error('Error fetching place details:', data.error);              Alert.alert('Error', 'Failed to fetch place details.');              return;            }            const fetchPhotoUrl = async (placeId, photoName) => {              const apiKey = 'key'; // Replace with your actual API key              const maxWidth = 400; // Specify your desired photo width              const maxHeight = 400; // Specify your desired photo height  try {    console.log('Fetching photo URL for photoName:', photoName);    const requestUrl = `https://places.googleapis.com/v1/${photoName}/media?maxWidthPx=400&maxHeightPx=400&key=${apiKey}`;    console.log('Request URL:', requestUrl);    const response = await fetch(requestUrl, {      method: 'GET',      headers: {'Content-Type': 'application/json',      },    });    console.log('Response status:', response.status);    console.log('Response headers:', response.headers);    if (response.ok) {      const contentType = response.headers.get('Content-Type');      console.log('Content-Type:', contentType);      if (contentType.includes('application/json')) {        const data = await response.json();        console.log('Response data:', data);        if (data.error) {          console.error('API error:', data.error);          return '';        }        return data.photoUri || '';      } else {        console.log('Response URL:', response.url);        return response.url;      }    } else {      console.error('Error fetching photo:', response.status);      const errorData = await response.json();      console.error('Error data:', errorData);      return '';    }  } catch (error) {    console.error('Error fetching photo:', error);    return '';  }};const photoName = data.photos && data.photos.length > 0 ? data.photos[0].name : '';console.log('Extracted photoName:', photoName);const placeCoverPhotoUrl = photoName ? await fetchPhotoUrl(data.id, photoName) : '';            // Update the venue details with the fetched data            setVenueDetails((prevDetails) => ({              ...prevDetails,              [dateString]: {                id: data.id || '',                name: data.name || '',                displayName: data.displayName?.text || '',                formattedAddress: data.formattedAddress || '',                shortFormattedAddress: data.shortFormattedAddress || '',                adrFormatAddress: data.adrFormatAddress || '',                location: data.location ? { latitude: data.location.latitude, longitude: data.location.longitude } : null,                plusCode: data.plusCode?.globalCode || '',                types: data.types || [],                viewport: data.viewport                  ? {                      northeast: {                        latitude: data.viewport.high?.latitude || '',                        longitude: data.viewport.high?.longitude || '',                      },                      southwest: {                        latitude: data.viewport.low?.latitude || '',                        longitude: data.viewport.low?.longitude || '',                      },                    }                  : null,                accessibilityOptions: data.accessibilityOptions || {},                businessStatus: data.businessStatus || '',                googleMapsUri: data.googleMapsUri || '',                iconBackgroundColor: data.iconBackgroundColor || '',                iconMaskBaseUri: data.iconMaskBaseUri || '',                primaryType: data.primaryType || '',                primaryTypeDisplayName: data.primaryTypeDisplayName?.text || '',                subDestinations: data.subDestinations ? data.subDestinations.map(destination => destination.name).join(', ') : '',                utcOffsetMinutes: data.utcOffsetMinutes || '',                currentOpeningHours: data.currentOpeningHours?.periods                  ? data.currentOpeningHours.periods.map(                      (period) => `${period.openDay} ${period.openTime} - ${period.closeDay} ${period.closeTime}`                    ).join(', ')                  : '',                currentSecondaryOpeningHours: data.currentSecondaryOpeningHours?.periods                  ? data.currentSecondaryOpeningHours.periods.map(                      (period) => `${period.openDay} ${period.openTime} - ${period.closeDay} ${period.closeTime}`                    ).join(', ')                  : '',                internationalPhoneNumber: data.internationalPhoneNumber || '',                nationalPhoneNumber: data.nationalPhoneNumber || '',                priceLevel: data.priceLevel || '',                rating: data.rating || '',                regularOpeningHours: data.regularOpeningHours?.periods                  ? data.regularOpeningHours.periods.map(                      (period) => `${period.openDay} ${period.openTime} - ${period.closeDay} ${period.closeTime}`                    ).join(', ')                  : '',                regularSecondaryOpeningHours: data.regularSecondaryOpeningHours?.periods                  ? data.regularSecondaryOpeningHours.periods.map(                      (period) => `${period.openDay} ${period.openTime} - ${period.closeDay} ${period.closeTime}`                    ).join(', ')                  : '',                userRatingCount: data.userRatingCount || '',                websiteUri: data.websiteUri || '',                placeCoverPhotoUrl: placeCoverPhotoUrl || '',              },            }));          } catch (error) {            console.error('Error fetching place details:', error);            Alert.alert('Error', 'Failed to fetch place details.');          }        };        return (<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={styles.container}><View key={dateString}><ScrollView contentContainerStyle={styles.scrollViewContent}><View style={styles.venueSearchContainer}><TextInput            style={styles.venueSearchInput}            placeholder="Search venue in database"            value={venueSearchQuery}            onChangeText={setVenueSearchQuery}          /><TouchableOpacity style={styles.venueSearchButton} onPress={handleVenueSearch}><Text style={styles.venueSearchButtonText}>Search</Text></TouchableOpacity></View>        {venueSearchResults.length > 0 ? (<View style={styles.venueSearchResultsContainer}>            {venueSearchResults.map(venue => (<TouchableOpacity                key={venue.id}                style={styles.venueSearchResult}                onPress={() => handleSelectFirestoreSuggestion(venue)}><Text>{venue.displayName}</Text></TouchableOpacity>            ))}</View>        ) : venueSearchQuery ? (<Text style={styles.venueSearchMessage}>Couldn't find venue in our database.</Text>        ) : null}<Text style={styles.stepInputTitle}>Search Venue</Text><TextInput  style={styles.input}  placeholder="Search venue"  value={searchQuery}  onChangeText={handleSearchVenue}/><ScrollView style={styles.suggestionsContainer}>  {suggestions.map((suggestion, index) => (<TouchableOpacity      key={index}      style={styles.suggestionItem}      onPress={() => handleSelectSuggestion(suggestion)}><Text>{suggestion.placePrediction.text.text}</Text></TouchableOpacity>  ))}</ScrollView><View key={dateString}><Text style={styles.stepInputTitle}>Selected Venue Details</Text>  {venueDetails[dateString] && (<><View style={styles.venueDetailsContainer}><View style={styles.venueImageContainer}>          {venueDetails[dateString]?.placeCoverPhotoUrl ? (<Image              source={{ uri: venueDetails[dateString]?.placeCoverPhotoUrl }}              style={styles.venueImage}            />          ) : (<View style={styles.venueImagePlaceholder} />          )}</View><View style={styles.venueTextContainer}><Text style={styles.venueDisplayName}>{venueDetails[dateString]?.displayName}</Text><Text style={styles.venueAddress}>{venueDetails[dateString]?.formattedAddress}</Text></View></View>      {venueDetails[dateString]?.location && (<View style={styles.venueMapContainer}><WebView            style={styles.venueMap}            originWhitelist={['*']}            source={{              html: `<iframe                  width="100%"                  height="100%"                  frameborder="0" style="border:0"                  referrerpolicy="no-referrer-when-downgrade"                  src="https://www.google.com/maps/embed/v1/place?key=key&q=${encodeURIComponent(venueDetails[dateString]?.displayName)}&zoom=20&maptype=satellite&language=en"                  maximum-zoom="21"                  allowfullscreen></iframe>              `,            }}          /></View>      )}</>  )}</View></ScrollView></View></KeyboardAvoidingView>        );      };      return (<View style={styles.container}><Text style={styles.title}>Create Tour</Text><View style={styles.stepsContainer}>            {[1, 2, 3, 4, 5].map((step) => (<View key={step} style={[styles.step, currentStep === step && styles.activeStep]} />            ))}</View><ScrollView contentContainerStyle={styles.scrollView}><View style={styles.formContent}>              {renderFormStep()}</View></ScrollView><View style={styles.navigation}>            {currentStep > 1 && (<TouchableOpacity style={styles.navButton} onPress={handlePrevStep}><Text style={styles.navButtonText}>Previous</Text></TouchableOpacity>            )}            {currentStep < 5 ? (<TouchableOpacity style={styles.navButton} onPress={handleNextStep}><Text style={styles.navButtonText}>Next</Text></TouchableOpacity>            ) : (<TouchableOpacity style={styles.navButton} onPress={handleSubmit}><Text style={styles.navButtonText}>Submit</Text></TouchableOpacity>            )}</View>          {isSubmitting && (<View style={styles.loadingContainer}><ActivityIndicator size="large" color="#E2384D" /><Text style={styles.loadingText}>Submitting...</Text></View>)}</View>      );    };    const styles = StyleSheet.create({      container: {        flex: 1,        justifyContent: 'flex-start',        paddingHorizontal: 20,        width: '100%',      },  // more style codeexport default CreateTour;  

I have tried using useCallback, usememo, and debounce but nothing is working. Does someone know how to fix this issue?


Viewing all articles
Browse latest Browse all 12201

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>