JohnCoene / firebase

Google FIrebase for shiny
https://firebase.john-coene.com
GNU Affero General Public License v3.0
171 stars 26 forks source link

Email verification not working with FirebaseUI #28

Closed itkonen closed 2 years ago

itkonen commented 2 years ago

I'm using firebase::FirebaseUI and firebase::useFirebase() in my app with email-password authentication among other providers (set_providers(email = TRUE, ...)), but sending the verification email is not working.

The problem seems to be that useFirebase does not include all necessary javascript functions for it to work properly. Particularly, it does not add "inst/packer/email-password.js" as a html dependency. This file includes message handlers for "fireblaze-send-verification-email" and others which, I guess, are need for email-password authentication to work properly when using FirebaseUI.

As a workaround, I included these dependencies manually in to my app:

  addResourcePath(
    "firebase-assets",
    system.file("packer", package = "firebase")
  )

and in the UI:

    htmlDependency(
      "firebase-email-password",
      utils::packageVersion("firebase"),
      src = c(href = "firebase-assets"),
      script = "email-password.js"
    )
JohnCoene commented 2 years ago

The dependencies are dynamically rendered from the server.

https://github.com/JohnCoene/firebase/blob/7832a10348bc8c8fbd293a8c4398c0b11605aa5d/R/class-email-password.R#L106

Could you share an example where this does not work?

itkonen commented 2 years ago

Here's a simple example of the problem.

My intended UX flow is that after a new user has signed on, FirebaseUI would send the verification email with the send_verification_email method and shiny would show a modal dialog with instructions. But send_verification_email seems to do nothing because theres no message handler on the UI side.

library(shiny)

shinyApp(
  ui = fixedPage(
    firebase::useFirebase(),
    firebase::firebaseUIContainer()
  ),
  server = function(input, output, session) {
    fb <-
      firebase::FirebaseUI$new(
        config_path = "my_firebase.rds"
      )$
      set_providers(
        email    = TRUE,
        google   = TRUE
      )$launch()

    ## VERIFY EMAIL ADDRESS
    email_verification_needed <- reactive(
      isFALSE(fb$get_signed_in()$response$emailVerified)
    )
    observeEvent(email_verification_needed(), {
      req(email_verification_needed())
      fb$send_verification_email()
      ## Here `fb$send_verification_email` sends a message for which the UI has no handler.
      showModal(modalDialog("instructions..."))
      fb$sign_out()
    }, ignoreInit = TRUE)
  }
)
JohnCoene commented 2 years ago

I don't think that is a bug. Are you 100% that a user with an unverified email address does not receive the email?

Google does not need to repeatedly verify email addresses if it is verified the email is simply not sent.

itkonen commented 2 years ago

Google sign-in works fine in this example, but if the user selects email-password sign-in, the verification email isn't being sent.

If I understand correctly, the send_verification_email method here

https://github.com/JohnCoene/firebase/blob/7832a10348bc8c8fbd293a8c4398c0b11605aa5d/R/class-ui.R#L165-L170

should be triggering this message handler and sending the verification email with Firebase's sendEmailVerification function.

https://github.com/JohnCoene/firebase/blob/7832a10348bc8c8fbd293a8c4398c0b11605aa5d/srcjs/components/email-password.js#L35-L46

But this isn't happening, because email-password.js isn't available on the client side.

Here's a suggestion I think might fix the problem, but I'm not quite sure if .render_deps will work here.