da2k / curso-reactjs-ninja

915 stars 322 forks source link

Projeto para uma Associação de crianças carentes #591

Closed pgstudies22 closed 2 years ago

pgstudies22 commented 2 years ago

Olá @fdaciuk!

Aceitei um trabalho voluntário para uma associação de crianças carentes onde o projeto consiste em um site informativo contendo um Blog e estou tendo algumas dificuldades relacionadas ao id do documento criado no banco de dados.

A minha intenção é criar um ID sequencial para todo documento, ou então até mesmo o ID gerado automaticamente pelo Firebase, o problema é que eu não consigo usar a referencia do documento e consequentemente seu ID, pois o objeto é inserido antes da declaração da variável que armazena a função de adicionar o doc.


Outro problema é na criação de um slug, pois como se trata de um blog, eu gostaria que o caminho de cada post fosse o seu título, porém formatado para funcionar em uma url.

Exemplo: {
  title: 'Um título',
  slug: 'um-titulo'
}

Segue abaixo o código que estou utilizando para capturar a imagem do input de seleção de arquivos no formulário e também o código para adicionar o doc.

const router = useRouter()

const handleUpload = async (event: any) => {
  event.preventDefault()
  const file = event.target.image.files[0]

  const postImagesRef = ref(storage, `images/${v4()}`)
  const uploadTask = uploadBytesResumable(postImagesRef, file)

  const uploadState = (snapshot: any) => {
    const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
    console.log(`Upload is ${progress}% done`)

    switch (snapshot.state) {
      case 'paused':
        console.log('Upload is paused')
        break
      case 'running':
        console.log('Upload is running')
        break
    }
  }

  const uploadError = (error: any) => alert(error)

  const getUrl = async () => {
    const collectionPosts = collection(db, 'posts')      
    const url = await getDownloadURL(uploadTask.snapshot.ref)

    const postData = {
      id: '',
      image: url,
      title: event.target.title.value,
      slug: '',
      description: event.target.description.value,
      author: 'Luis Guedes',
      date: serverTimestamp()
    }

    const docRef: any = await addDoc(collectionPosts, postData)
    router.push('/dashboard')
  }

  uploadTask.on('state_changed', uploadState, uploadError, getUrl)  
}
{posts.map(({ item, index }: any) => (
  <li key={index} className='list-none'>
    <Link href={`/relatorios/posts/${item.id}`}>
      <a>
        <BlogCard 
          image={item.image}
          title={item.title}
          description={item.description}
          authorImage={item.authorImage}
          author={item.author}
          date={item.date}
        />
      </a>
    </Link>
  </li>
))}

@fdaciuk

fdaciuk commented 2 years ago

Fala @pgstudies22! Sobre o ID, não é uma boa ideia usar IDs sequenciais, pois você pode ter problemas de race condition em algum momento. O ideal é usar algo como um UUID. Hoje nem precisa de lib pra isso, você pode usar o crypto.randomUUID() no browser, por exemplo, para gerar UUIDs na versão 4 (que é a mais segura atualmente).

E sobre o slug, fazer na mão nunca é uma boa ideia, pois existem várias regras que você precisa levar em consideração. Recomendo uma lib chamada slugify pra fazer o trabalho =)

pgstudies22 commented 2 years ago

Nossa, que massa!

Bem mais claro agora o caminho que devo seguir, professor.

Vou fechar a issue, muito obrigado =D

@fdaciuk

fdaciuk commented 2 years ago

Qualquer dúvida, avisa ae! :D