Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The subscribe function must return a function to unsubscribe. #4088

Open
surejainam opened this issue Feb 6, 2025 · 0 comments
Open

The subscribe function must return a function to unsubscribe. #4088

surejainam opened this issue Feb 6, 2025 · 0 comments

Comments

@surejainam
Copy link

surejainam commented Feb 6, 2025

Bug report

Getting this error even though unsubscribe function is returned

Repro Steps / Code Example

export const subscribeToFirebase = (
  uuid: string,
  onData: (data: UserData | null) => void,
  onError: (error: Error) => void
): (() => void) => {
  // Early exit for authentication
  if (!authService.isAuthenticated()) {
    onError(new Error("Not authenticated"));
    return () => {};
  }

  const db = firebaseService.getDb();
  const docRef = doc(db, MY_COLLECTION, uuid);

  // Set up the snapshot listener - returns unsubscribe function immediately
  const unsubscribe = onSnapshot(
    docRef,
    (snapshot) => {
      const baseData = snapshot.data() as UserData;
      
      if (!baseData) {
        onData(null);
        return;
      }

      // First emit the base data immediately
      onData(baseData);

      // Then process the enhanced data asynchronously
      if (baseData.LN) {
        Promise.all(
          baseData.LN.map(async (atom) => {
            try {
              const rates = await getRates(atom.TYP, baseData.SCR);
              return {
                ...atom,
                MR: rates.market,
                PR: rates.peer,
              };
            } catch (error) {
              console.error('Error fetching rates for atom:', error);
              return atom;
            }
          })
        )
        .then((updatedAtoms) => {
          onData({
            ...baseData,
            LN: updatedAtoms,
          });
        })
        .catch((error) => {
          console.error('Error processing atoms:', error);
          // Data was already emitted, so this error doesn't break the flow
        });
      }
    },
    (error) => {
      console.error('Snapshot subscription error:', error);
      onError(error);
    }
  );

  // Return the unsubscribe function immediately
  return unsubscribe;
};

export const useUserAtoms = () => {
  const { isAuthenticated, error: authError, uuid } = useAuthToken();

  
  const { data, error } = useSWRSubscription<UserData | null>(
    isAuthenticated && uuid ? CACHE_KEY.userAtom(uuid) : null,
    (key: string, { next }: SWRSubscriptionOptions) => {
      console.log('Setting up subscription...');
      
      // Create stable cleanup function
      const noop = () => {};
      
      if (!uuid || !isAuthenticated) {
        console.log('Early return - no uuid or not authenticated');
        return noop;
      }

      let unsubscribe = noop;

      try {
        unsubscribe = subscribeToUserAtom(
          uuid,
          (data) => {
            console.log('Received data:', data);
            if (data) {
              next(null, data);
            } else {
              next(null, null);
            }
          },
          (error) => {
            console.error('Subscription error:', error);
            next(error);
          }
        );

        console.log('Unsubscribe type:', typeof unsubscribe);
        
        // Return cleanup function
        return () => {
          console.log('Cleaning up subscription');
          if (typeof unsubscribe === 'function') {
            unsubscribe();
          }
        };
      } catch (error) {
        console.error('Setup error:', error);
        next(error instanceof Error ? error : new Error('Subscription setup failed'));
        return noop;
      }
    }
  );

  return {
    isAuthenticated,
    atom: data,
    isLoading: !error && !data,
    isError: authError || error || (!uuid && "UUID not provided")
  };
};



Additional Context

SWR version. 2.3.2
NextJS version 15
Add any other context about the problem here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant