我开始创建一个可以从中购买元素的应用程序。
可能是这样的:
您可以在其中看到 Image、Name of product 和 Price。好吧,我已经有了一个使用 Authentication Firebase 制作的 Sign-in with Google 并将其存储在 Firebase 数据库 中,我想创建以下是@Alex Mamo 向我推荐的结构:
Firebase-root
|
--- users
| |
| --- uid1
| |
| --- //user details (name, age, address, email and so on)
| |
| --- products
| |
| --- productId1 : true
| |
| --- productId2 : true
|
--- products
| |
| --- productId1
| | |
| | --- productName: "Apples"
| | |
| | --- price: 11
| |
| |
| --- users
| |
| --- uid1: true
| |
| --- uid2: true
|
--- purchasedProducts
| |
| --- uid1
| |
| --- productId1: true
| |
| --- productId2: true
|
--- paidProducts
| |
| --- uid2
| |
| --- productId3: true
|
--- availableProducts
| |
| --- uid3
| |
| --- productId4: true
制作像我这样简单的应用程序看起来不错。 因为场景很简单:
从一开始,我就将 uid 存储在 users 中。
我不知道的是;
Google Play 控制台 上创建与 Firebase 数据库 相同的产品?我已经创建了 1 个产品来在 Google Play 控制台 上进行测试,我还必须在我的应用程序上创建产品吗(我是说在 Firebase 数据库 上)?为了实现应用内计费,我正在关注这个 tutorial但我找到了这个android-inapp-billing-v3库,但看起来不错。
如果你们中有人使用过应用内购买并创建了项目并且知道如何从 Google Play Console 获取它们,请随时分享如何操作的演示。
我已经知道如何购买我最终使用这个 Library 的元素了,问题是在我的 Login 页面上我有 firebase 的 db create 我的意思是我在那里放置了用户 ID 和电子邮件......我是否也必须在那里添加所有产品?
最佳答案
我将对您计划的数据库结构进行一些更改,希望能稍微简化一下。
我们将有两种类型的保存数据:
第一种类型
是一个节点数据,您将添加它并手动准备它,我们将其称为“产品”。在此产品节点中,您将添加从 Google Play 控制台获得的产品 ID,然后为其提供一些类似的详细信息:
Products
|
|--------Wood_id
| |
| |--name : "wood"
| --price: "10"
| -- ........
|
|---------Iron_id
|
|--name : "iron"
--price: "20"
-- ........
好的,现在让我们定义上图:
Wood_id 或 Iron_id:代表您在 Google Play 控制台中创建产品时使用的确切 ID。 (((您在数据库中手动输入它及其详细信息))
名称:代表要在回收站 View 中显示的项目的名称((也可以手动输入所有这些详细信息))。
价格:积分或您决定的任何东西。
所以这些是您在 Firebase 控制台的数据库树中手动输入的内容。
在回收站 View 中填充时,它看起来像那样
|---------------|
| wood |
------------------
| iron |
| |
-----------------
您可以使用 Firebase UI 实现此目的((这将使您更容易检索节点并在 RecyclerView 中查看它们))。
好的,到现在为止,我们能够向用户展示产品并在产品列表中查看它们((每个项目都带有它和 Id 等于 google play 控制台上的 id))
第二种
是我们将从应用程序添加的数据类型,即(用户)节点和(已购买商品)节点。
users节点是这样的
Users
|
|--------user1
| |
| |--name : "..."
| --e-mail: "..."
| -- ........
|
|---------user2
|
|--name : "..."
--e-mail: "..."
-- ........
好的,这是一个由您来添加的节点,通常在创建用户((注册))之后出现,但您似乎已经使用谷歌登录完成了这一点。
所以这个节点不是很重要,但是你可以根据需要添加。
现在看看我们将要做什么。我们将让用户点击一个项目,然后我们将检查该项目是否存在于他的列表中,如果不存在,我们将向他显示付款意向。在他/她购买了元素后,我们将把它添加到(已购买的元素)节点中,如下所示:
Purchased items
|
|--------user1
| |
| |--Wood_id : "any_value"
| --Iron_id: "any_value"
|
|
|---------user2
|
|--Iron_id : "any_value"
上面的树表示用户 1 购买了(木头和铁),而用户 2 只购买了(铁)。
例如,当用户 2 单击木材时,我们将获取与木材关联的产品 ID,即 (Wood_id),我们将使用 firebase 运行一个值事件监听器,我们将检查用户 2 是否具有 (Wood_id),在我们的案例 user2 没有木头。所以如果你想要你提到的计费库并通过(Wood_id)从谷歌播放控制台购买,你可以在这里使用,并且在你提到的这个库的听众中检查付款是否成功(在这里你为 user2 添加“Purchased items”节点中的 Wood_id,以便用户 2 下次单击时 firebase 将运行一个监听器并且不会再次显示付款)。
这就是您使用您想要使用的库的方式。
更新
如何在回收站 View 中检索数据库(产品)。
首先添加最新的firebase数据库和firebase ui
compile 'com.google.firebase: firebase-database: 11.4.2'
compile 'com.firebaseui: firebase-ui-database: 3.1.0'
之后,您需要创建一个 java 类,在其中调用它 (ProductsClass) 添加这些:
public class ProductsClass{
//these should be the same name as keys in your database
public String name;
public String product_id;
public String state;
//empty constructor
public ProductsClass(){
}
public ProductsClass(String name, String product_id, String state){
this.name=name;
this.product_id=product_id;
this.state=state;
}
public String getName(){
return name;
}
public void setName(){
this.name=name;
}
public String getProduct_id(){
return product_id;
}
public void setProduct_id(){
this.product_id=product_id;
}
public String getState(){
return state;
}
public void setState(){
this.sate=state;
}
}
现在在您的(产品 Activity )中
private Recyclerview products_recycler;
private FirebaseAuth mauth;
private DatabaseReference products_ref;
private String currentuser;
//in on create
products_recycler=find it by id......
mauth=FirebaseAuth.getInstance();
currentuser=mauth.getCurrentUser().getUid();
products_ref=FirebaseDatabase.getInstance().getReference().child("products");
//manger
products_recycler.setHasFixedSize(true);
products_recycler.setLayoutManager(new LinearLayoutManager(this));
//in onstart
FirebaseRecyclerOptions< ProductsClass > options =
new FirebaseRecyclerOptions.Builder< ProductsClass >()
.setQuery(products_ref, ProductsClass.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter< ProductsClass, ProductsHolder>(options) {
@Override
public ProductsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflate the single recycler view layout(item)
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.productslayout, parent, false);
return new ProductsHolder(view);
}
@Override
protected void onBindViewHolder(ProductsHolder holder, int position, ProductsClass model) {
//here you set stuff in items , get data, ....
//model is your class model (you get data from it)
}
};
// now set adapter
adapter.startListening();
products_recycler.setAdapter(adapter);
//make a static class called ProductsHolder in the same activity
public static class ProductsHolder extends RecyclerView.ViewHolder{
View view;
public ProductsHolder(View itemView){
view= itemView;
}
//what ever methods you need to add
}
注意:R.layout.productslayout 是回收站 View 中每个项目的自定义布局。
通过这种方式,您可以在任何 Activity 中检索您想要的任何节点。
引用链接:this link
关于android - In-App billing 连接到 Firebase 并获取 Products,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47438092/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el