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

forceFetch without using node (without id) #858

Closed
legomind opened this issue Feb 20, 2016 · 10 comments
Closed

forceFetch without using node (without id) #858

legomind opened this issue Feb 20, 2016 · 10 comments

Comments

@legomind
Copy link

I have an app that uses Hawk for authentication (hueniverse/hawk)

The authentication is driven using a plain http endpoint /api/auth
Edit: I have moved authentication to a graphql mutation

My graphQL endpoint has the following relay compatible schema:

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    node: nodeField,

    viewer: {
      type: UserType,
      resolve ({ auth }) { //root param is the http request object
        return auth.isAuthenticated
          ? User.GetById(auth.credentials.authKey.ownerId)
          : null
      },
    },
...
}

So when an unauthenticated user first visits the site, the following query is run:

query Client {
  viewer {
    ...F3,
    id
  }
}

fragment F0 on User {
  firstName,
  id,
  lastName
}

fragment F1 on User {
  id,
  permissions
}

fragment F2 on User {
  ...F0,
  ...F1,
  id
}

fragment F3 on User {
  ...F2,
  id
}

Since this query is lacking Hawk credentials in the http headers, the above query returns null, causing the app to render a login form.

Upon login, the app will make a call to /api/auth in order to get credentials for future graphQL calls
Edit: Now using mutations instead

Then the login page will call this.props.relay.forceFetch() in order to update the required user data.

However, since the initial call returns null relay simply skips the graphQL call because it does not have an id query node with.

If I refresh the entire page, the viewer prop contains the user data of the logged in user, and if I login again, the following query runs:

query LoginPage_ViewerRelayQL($id_0:ID!) {
  node(id:$id_0) {
    ...F2,
    __typename,
    id
  }
}

fragment F0 on User {
  firstName,
  id,
  lastName
}

fragment F1 on User {
  id,
  permissions
}

fragment F2 on User {
  ...F0,
  ...F1,
  id
}

Conversely, a similar issue arises when refreshing data after logout. this.props.relay.forceFetch() runs the above node query instead of querying viewer.

How can I force relay to use the inital query to refetch the currently logged in user?

@legomind legomind changed the title forceFetch without using node forceFetch without using node (without id) Feb 20, 2016
@legomind
Copy link
Author

perhaps similar to #742?

@schickling
Copy link
Contributor

@legomind did you eventually figure out the problem or find a workaround? Facing a similar scenario at the moment.

@legomind
Copy link
Author

legomind commented Mar 3, 2016

I found a very hacky workaround.

Basically, I wrapped the User Type in a ViewerType and gave viewer an id of 1, even when user is null.

@schickling
Copy link
Contributor

I had the same idea but feels really wrong 🐵

@josephsavona
Copy link
Contributor

@legomind, @schickling - are logged out users able to access any GraphQL data in your apps? An approach we often use is to not even query the GraphQL server until the user is logged in - this avoids having fields start out null when they really aren't.

Another approach going forward will be to have one RelayContext (currently not public API yet) before the user logs in to store unauthenticated data, and then create a new context after the user logs in. In the meantime, though, could you work around this by not issuing queries until login?

@legomind
Copy link
Author

legomind commented Mar 3, 2016

@schickling Yes, it feels very, very wrong.

@josephsavona Currently, authentication is actually performed using mutations (I just updated the original post), so that approach would not work. Even if I was to move authentication out of graphql, how would I prevent the initial queries? Just avoid rendering a RootContainer?

@josephsavona
Copy link
Contributor

how would I prevent the initial queries? Just avoid rendering a RootContainer?

@legomind Yup.

@schickling
Copy link
Contributor

Thanks for the clarification @josephsavona! Is there any rough timeline for the multiple RelayContext feature?

@josephsavona
Copy link
Contributor

Is there any rough timeline for the multiple RelayContext feature?

Soon-ish - I posted an update on the main task #558

@josephsavona
Copy link
Contributor

We added support for multiple contexts/environments a few releases back, which addresses the logout or change-user case.

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

3 participants