Firebase和GraphQL [关闭]


75

是否有人对GraphQL和Firebase有任何经验?我想一个将firebase调用放置在相关字段的解析器中,并将一些变量从组件的props传递到查询的参数中。

我们如何使用GraphQL在Firebase中插入新数据?



您可以尝试apollo-link- firebase github.com/Canner/apollo-link-firebase,它允许您使用带有没有后端服务的graphQL查询firebase。
williamC

4
我们只是构建了一个开源工具,通过将数据实际迁移到Postgres来帮助您从Firebase迁移到实时GraphQL。github.com/hasura/graphql-engine/tree/master/community/tools/…–
iamnat

我赞同前面的评论。Hasura很棒!
leetheguy

在GraphQL服务器中使用Firebase的开源项目:github.com/rwieruch/nextjs-firebase-authentication
Robin Wieruch

Answers:


57

要回答您的问题,有三种方法可以解决此问题。

1. Firebase和GraphQL

如果您设置使用Firebase,则可以将Firebase的API一对一映射到GraphQL查询和变异。

您当然可以将Firebase API包装到GraphQL解析器中,然后以这种方式进行调用。这是一个很好的例子

const ref = path => firebase.database().ref(path)
const getValue = path => ref(path).once('value')
const mapSnapshotToEntities = snapshot => snapshot.val().map((value, id) => ({ id, ...value }))
const getEntities = path => getValue(path).then(mapSnapshotToEntities)

const resolvers = {
    Author: {
        posts(author) {
            return getEntities('posts').then(posts => filter(posts, { authorId: author.id }))
        },
    },

    Post: {
        author(post) {
            return getEntities('authors').then(posts => filter(authors, { id: authorId }))
        },
    },
};

本质上,您在这里所做的就是将Firebase用作数据库,该数据库可以正常工作,直到您想在解析器中以关系方式查询数据为止。如果无法在数据存储顶部的服务器端执行联接,则您将向解析器中的Firebase发出大量往返请求,以仅满足单个请求。

大多数人使用Firebase的原因在于其实时功能,而不仅仅是主要作为数据存储,因为在这方面的数据关系建模工具相当缺乏。这样,您最好使用其他数据源迁移到GraphQL。

2. GraphQL后端即服务

考虑到您可以使用Firebase等BaaS产品,您可以考虑切换到GraphQL BaaS。

3.自托管的GraphQL

如果您愿意使用自己的数据存储切换到自托管解决方案,那么它也有很多好处。以下是一些大人物:

  • 使用自己的数据存储的灵活性,也许可以满足您特定应用程序的需求

  • 自定义查询和变异

  • 本机添加自定义逻辑,而不是通过API中附加到Webhooks的微服务

  • 推出自己的身份验证和许可机制

  • 可能是一种低成本的解决方案


2
上面所有的好东西!是否有一个示例,说明有人从Firebase迁移来使用您可以提供的Scaphold?
山姆·米切尔

3
是的 随时将Neat App作为一款出色的应用程序进行检查,该应用程序已从Firebase移出,可以使用Scaphold。也请随时与Scaphold的Slack联络,并询问其他这样做的人。
自从

1
应该标记为答案!
parohy

@vince我在某个地方读到scaphold.io不再营业了,对吗?(我意识到网站仍在运行中)
k00k

1
现在还包括AWS AppSync
Vyacheslav

17

我强烈不同意这里的一些建议。GraphQL可以以关系方式使用,但也可以以NoSQL方式使用。带有RTD(实时数据库)和Firestore的Firebase应该建模为NoSQL数据库,因为它是NoSQL数据库!这种方法需要权衡:

1.优化阅读:

作为NoSQL数据库,应将集合建模为客户端(移动或Web)中的视图,因此,当您进行查询时,所有内容都已合并,并且不必在客户端或Firebase函数中创建计算道具。这种方法使阅读真正非常快。

2.取消优化写入:

这里的主要权衡是,如果您触摸相关数据(例如更新用户名,个人资料图片等),则您有责任更新数据库中的每个文档。在这种情况下,您应该在数据库中找到每个文档(例如,帖子,评论等)并确保原子性。如果您的应用程序的读取操作要比写入操作多(例如,博客,例如7000次读取到1次写入),则建议使用此方法。

3.易于扩展:

由于您的馆藏与其他文档没有严格的关系,因此您可以在一个服务器中拥有一个完整的馆藏,也可以将其拆分给许多服务器。(这就是为什么Firebase像DynamoDB这样的扩展规模便宜的原因。)

GraphQL只是一种查询语言。它应该使您查询事情变得容易,但是它不应该决定如何对数据库建模。您应该指示如何对数据库,查询和变异进行建模。


16

TL; DR: GraphQL在Firebase不足之处发光。强大的数据建模,灵活高效的查询以及开放的规范都是GraphQL必不可少的组成部分,而Firebase缺少这些功能。

强大的数据建模

由于其有限的数据建模,Firebase受到了很多批评。基本上,您的数据被构造为一个巨大的JSON,可多次声明相同的数据。起初看起来很方便的结果是,每当您需要更新数据时都会导致客户端代码难以管理,因为您必须手动跟踪对同一数据的所有引用。

另一方面,在GraphQL中使用的数据结构非常直观,而且考虑起来很熟悉,因为它被建模为图形。使用IDL语法,我们可以轻松地描述称为GraphQL模式的数据模型。对于Twitter应用,架构如下所示:

type Tweet {
  id: ID!
  title: String!
  author: User! @relation(name: "Tweets")
}

type User {
  id: ID!
  name: String!
  tweets: [Tweet!]! @relation(name: "Tweets")
}

在这里,我们定义了两种类型TweetUser一些标量性质,也是一个一个一对多的关系之间UserTweet。单个数据项称为节点-用户节点可以连接到许多tweet节点。除了Firebase的JSON方法外,此数据结构既简单又灵活。

灵活高效的查询

GraphQL的灵活查询功能是其主要优点之一。查询是分层的,这意味着您可以指定镜像图结构的数据需求。在我们的Twitter示例中,我们可能有一个查询来获取所有用户及其推文:

query {
  allUsers {
    id
    name
    tweets {
      title
    }
  }
}

请注意,我们可以自由地包含或保留要查询的字段,甚至可以查询各种关系。这意味着我们既不需要执行多个查询,也不需要查询不需要的数据,这使得GraphQL查询非常高效。

在混合中添加查询参数,我们可以添加自定义顺序或过滤器之类的功能以获得强大的GraphQL API

Firebase根本无法实现所有这些功能。

实时数据

Firebase的实时功能使它如此流行-但是由于GraphQL社区即将就实时性达成共识,因此Firebase的最大优势也被取消了。我建议使用有关GraphQL订阅的视频教程,以更好地理解基本概念

结论

因此,回答您的问题:GraphQL在大多数方面都超过了Firebase,使其成为首选。

如果您对GraphQL感兴趣,我建议您查看Graphcool,它结合了GraphQL的优势和强大的功能,例如内置身份验证以及到AWS Lambda的灵活钩子或其他无服务器功能,以实现自定义业务逻辑。

免责声明:我在Graphcool工作:)


1
@martktani我正在将一个由“帖子”和“评论”组成的react-redux-thunk-firebase项目重构为react-redux-graphql。Graphcool中是否有一个通过从firebase导入json数据来启用创建架构/节点的过程?我想问一下,一次必须重新输入所有现有数据的想法太麻烦了,无法考虑。
TheoG

1
抱歉,刚看到问题!这是用于将JSON数据导入GraphQL的教程。让我知道是否有帮助!
marktani

你好marktani。我看到您的答案的某些部分是从此处复制的,而没有明确说明这些部分是从该位置复制的(属性+引号)。我假设您是从该链接写了read.me吗?如果是这样,也许您可​​以使这一点更加清楚?(我一直在寻找复制的部分,因此在评论)。如果不是,您是否可以通过引用复制的部分并弄清楚从何处复制内容来使其清晰。
TT。

1
感谢您的问题,@ TT。实际上,您引用的链接中的文本是从此处我的答案中复制的文本。
marktani

1
哦,我现在看到了:)因此是反向链接。很高兴知道。
TT。

6

您可以在本地使用graphql和firebase。所有繁重的工作都可以在Webworker中完成,以避免在解决请求时阻塞UI。

关于“解决请求所必需的许多往返”的一句话:如果您不介意传输的数据,那没什么大不了的,因为所有“往返”都合并在同一套接字框架中。但是,如果您确实想避免使用大型框架,则只需dataloader在Firebase数据库的前面放置一些内容即可。

对于实时更新,您只需要从firebase订阅实时事件并将其发送到Webworker,即可将其转换为可以通过您的模式解决的实际graphql订阅。

您可以在我的中篇文章中找到有关此问题的更多信息:带有Firebase,GraphQL和apollo-client 2.0的“仅客户端”实时Web应用程序

希望能有所帮助!


5

您必须使用Firebase吗?有些特定于GraphQL的服务可能会提供您想要的东西。https://scaphold.io是一家YC奖学金公司,该公司看起来特别有前途,可为您提供类似Firefire的体验,但它由GraphQL提供支持。


2
scaphold.io是否足以被社区关注,至少在中期可以可靠?
制造于月球

4
嗨,我是Scaphold.io的Vince ,我想我可以在这里打电话。对于您的问题,是的,我们有非常强大的社区关注者,我们不会去任何地方。现在,我们已经在该平台上发展了数千个应用程序,并且目前在YC Core程序(W17)中。如果您想参与其中,这是我们的Slack(slack.scaphold.io)。
文斯-

2
scaphold是可信任的,我真的很喜欢管道的功能,该功能可以帮助您轻松连接所有API。
Amazingandyyy

5
啊,它走了。倒闭 似乎您的顾虑是有效的@MadeInMoon
Nicolas Marshall,

@NicolasMarshall很好看!关于文斯的回答,令我感到难过的是,即使是一个“强大的社区”也可能会关闭,并涉及到所有人类和代码方面的影响
Made in Moon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.