Skip to content

Commit

Permalink
custom hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
jdgamble555 committed Oct 16, 2022
1 parent 67a64e9 commit 9771274
Show file tree
Hide file tree
Showing 17 changed files with 6,316 additions and 1,224 deletions.
2 changes: 1 addition & 1 deletion components/AuthCheck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useContext } from 'react';
import { UserContext } from '@lib/context';

// Component's children only shown to logged-in users
export default function AuthCheck(props: any) {
export default function AuthCheck(props: any): JSX.Element {
const { username } = useContext(UserContext);
return username ? props.children : props.fallback || <Link href="/enter">You must be signed in</Link>;
}
5 changes: 3 additions & 2 deletions components/HeartButton.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { auth } from '@lib/firebase';
import { useDocument } from 'react-firebase-hooks/firestore';
import { useDocument } from '@lib/hooks';
//import { useDocument } from 'react-firebase-hooks/firestore';
import { increment, writeBatch, doc, getFirestore } from "firebase/firestore";


// Allows user to heart or like a post
export default function Heart({ postRef }: any) {

const uid: any = auth?.currentUser?.uid;

// Listen to heart document for currently logged in user
const heartRef = doc(getFirestore(), postRef.path, 'hearts', uid);
const [heartDoc] = useDocument(heartRef);
Expand Down
4 changes: 2 additions & 2 deletions components/ImageUploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Loader from './Loader';
import { ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage';

// Uploads images to Firebase Storage
export default function ImageUploader() {
export default function ImageUploader(): JSX.Element {
const [uploading, setUploading] = useState(false);
const [progress, setProgress] = useState(0);
const [downloadURL, setDownloadURL] = useState(null);
Expand All @@ -21,7 +21,7 @@ export default function ImageUploader() {
setUploading(true);

// Starts the upload
const task = uploadBytesResumable(fileRef, file)
const task = uploadBytesResumable(fileRef, file);

// Listen to updates to upload task
task.on(STATE_CHANGED, (snapshot) => {
Expand Down
2 changes: 1 addition & 1 deletion components/Metatags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default function Metatags({
title = 'The Full Next.js + Firebase Course',
description = 'A complete Next.js + Firebase course by Fireship.io',
image = 'https://fireship.io/courses/react-next-firebase/img/featured.png',
}) {
}): JSX.Element {
return (
<Head>
<title>{title}</title>
Expand Down
2 changes: 1 addition & 1 deletion components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useContext } from 'react';
import { UserContext } from '@lib/context';

// Top navbar
export default function Navbar() {
export default function Navbar(): JSX.Element {

const { user, username } = useContext(UserContext);

Expand Down
22 changes: 11 additions & 11 deletions components/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Img from 'next/image';

export default function UserProfile({ user }: { user: any}) {
return (
<div className="box-center">
<Img src={user.photoURL || '/hacker.png'} width={150} height={150} objectFit="cover" className="card-img-center" />
<p>
<i>@{user.username}</i>
</p>
<h1>{user.displayName || 'Anonymous User'}</h1>
</div>
);
}
export default function UserProfile({ user }: { user: any }) {
return (
<div className="box-center">
<Img src={user.photoURL || '/hacker.png'} width={150} height={150} objectFit="cover" className="card-img-center" />
<p>
<i>@{user.username}</i>
</p>
<h1>{user.displayName || 'Anonymous User'}</h1>
</div>
);
}
26 changes: 3 additions & 23 deletions lib/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getAuth, GoogleAuthProvider } from "firebase/auth";
import { getFirestore, collection, where, getDocs, query, limit } from "firebase/firestore";
import { getStorage } from "firebase/storage";


const firebaseConfig = {
apiKey: 'AIzaSyBX5gkKsbOr1V0zxBuSqHWFct12dFOsQHA',
authDomain: 'nextfire-demo.firebaseapp.com',
Expand All @@ -12,15 +13,6 @@ const firebaseConfig = {
appId: '1:827402452263:web:c9a4bea701665ddf15fd02',
};

// Initialize firebase
// let firebaseApp;
// let firestore;
// if (!getApps().length) {
// // firebase.initializeApp(firebaseConfig);
// initializeApp(firebaseConfig);
// firestore = getFirestore();
// }

function createFirebaseApp(config: FirebaseOptions) {
try {
return getApp();
Expand All @@ -29,44 +21,32 @@ function createFirebaseApp(config: FirebaseOptions) {
}
}

// const firebaseApp = initializeApp(firebaseConfig);
const firebaseApp = createFirebaseApp(firebaseConfig);



// Auth exports
// export const auth = firebase.auth();
export const auth = getAuth(firebaseApp);
export const googleAuthProvider = new GoogleAuthProvider();

// Firestore exports
export const firestore = getFirestore(firebaseApp);
// export const firestore = firebase.firestore();
// export { firestore };
// export const serverTimestamp = serverTimestamp;
// export const fromMillis = fromMillis;
// export const increment = increment;

// Storage exports
export const storage = getStorage(firebaseApp);
export const STATE_CHANGED = 'state_changed';

/// Helper functions


/**`
* Gets a users/{uid} document with username
* @param {string} username
*/
export async function getUserWithUsername(username: string) {
// const usersRef = collection(firestore, 'users');
// const query = usersRef.where('username', '==', username).limit(1);
export async function getUserWithUsername(username: string): Promise<any> {

const q = query(
collection(firestore, 'users'),
where('username', '==', username),
limit(1)
)
);
const userDoc = (await getDocs(q)).docs[0];
return userDoc;
}
Expand Down
82 changes: 76 additions & 6 deletions lib/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { useEffect, useState } from 'react';
import { useAuthState } from 'react-firebase-hooks/auth';
//import { useAuthState } from 'react-firebase-hooks/auth';
import { auth } from '@lib/firebase';
import { doc, getFirestore, onSnapshot } from 'firebase/firestore';
import {
doc,
DocumentData,
DocumentReference,
getDoc,
getFirestore,
onSnapshot,
Query,
QuerySnapshot
} from 'firebase/firestore';
import { Auth, onIdTokenChanged, User } from 'firebase/auth';

export function useUserData() {
export function useUserData(): any {
const [user] = useAuthState(auth);
const [username, setUsername] = useState(null);

Expand All @@ -12,11 +22,9 @@ export function useUserData() {
let unsubscribe;

if (user) {

// const ref = firestore.collection('users').doc(user.uid);
const ref = doc(getFirestore(), 'users', user.uid);
unsubscribe = onSnapshot(ref, (doc) => {
setUsername(doc.data()?.username);
if (doc) setUsername(doc.data()?.username);
});
} else {
setUsername(null);
Expand All @@ -26,4 +34,66 @@ export function useUserData() {
}, [user]);

return { user, username };
}

// added this due to problems with react-firebase-hooks

export function useAuthState(auth: Auth): any {
const [user, setCurrentUser] = useState<User | null>(null);

useEffect(() => {
return onIdTokenChanged(auth, (_user) => {
setCurrentUser(_user ?? null);
});
}, [auth]);
return [user];
}

export function useDocument(ref: DocumentReference): any {
const [_doc, setDoc] = useState<DocumentData | null>(null);

useEffect(() => {
// turn off realtime subscription
return onSnapshot(ref, (snap) => {
setDoc(snap.exists() ? snap : null);
});
}, [ref]);
return [_doc];
}

export function useDocumentData(ref: DocumentReference): any {
const [_doc, setDoc] = useState<DocumentData | null>(null);

useEffect(() => {
// turn off realtime subscription
return onSnapshot(ref, (snap) => {
setDoc(snap.exists() ? snap.data() : null);
});
}, [ref]);
return [_doc];
}

export function useDocumentDataOnce(ref: DocumentReference): any {
const [_doc, setDoc] = useState<DocumentData | null>(null);

useEffect(() => {
// turn off realtime subscription
getDoc(ref).then(snap => {
setDoc(snap.exists() ? snap.data() : null);
});
return;
}, [ref]);
return [_doc];
}

export function useCollection(ref: Query): any {
const [_doc, setDoc] = useState<QuerySnapshot | null>(null);

useEffect(() => {
// turn off realtime subscription
return onSnapshot(ref, (snap) => {
setDoc(!snap.empty ? snap : null);
});
}, [ref]);
return [_doc];
}
Loading

0 comments on commit 9771274

Please sign in to comment.