google-api-ruby-client
google-api-ruby-client copied to clipboard
AdMob API undefined method `has_key?' for #<Array:0x007fbf08109568>
Environment details
- OS: macOS 11.0
- Ruby version: ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin19]
- Gem name and version: google-api-client (0.44.0), googleauth (0.13.1)
Steps to reproduce
- Run example code
Code example
require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'google/apis/admob_v1'
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
Admob = Google::Apis::AdmobV1
def self.get_credentials
scope = "https://www.googleapis.com/auth/admob.report"
client_id = Google::Auth::ClientId.from_file("googleauth/client-secrets.json")
token_store = Google::Auth::Stores::FileTokenStore.new(file: "googleauth/tokens.yaml")
authorizer = Google::Auth::UserAuthorizer.new(client_id, scope, token_store)
user_id = "default"
credentials = authorizer.get_credentials(user_id)
if credentials.nil?
url = authorizer.get_authorization_url(base_url: OOB_URI)
puts "Open the following URL in your browser and authorize the application."
puts url
puts "Enter the authorization code:"
code = gets
credentials = authorizer.get_and_store_credentials_from_code(
user_id: user_id, code: code, base_url: OOB_URI)
end
credentials
end
publisher_id = "pub-XXXXXXXXXXXXXXXX"
admob = Admob::AdMobService.new
result = admob.generate_network_report "accounts/#{publisher_id}",
{report_spec: {
date_range: {start_date: {year: 2020, month: 1, day: 1}, end_date: {year: 2020, month: 9, day: 1}},
metrics: ["ESTIMATED_EARNINGS"],
}},
options: {authorization: get_credentials, retries: 5}
➜ ruby sample.rb
/Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/hash/binding.rb:12:in `read': undefined method `has_key?' for #<Array:0x007fbf08109568> (NoMethodError)
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/deserializer.rb:11:in `block in <module:Representable>'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/pipeline.rb:18:in `evaluate'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/pipeline.rb:10:in `block in call'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/pipeline.rb:9:in `each'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/pipeline.rb:9:in `inject'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/pipeline.rb:9:in `call'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/binding.rb:37:in `uncompile_fragment'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable.rb:53:in `block in call'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable.rb:51:in `each'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable.rb:51:in `call'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable.rb:70:in `representable_map!'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable.rb:37:in `update_properties_from'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/hash.rb:30:in `from_hash'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/json.rb:39:in `from_json'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/lib/google/apis/core/api_command.rb:87:in `decode_response_body'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/lib/google/apis/core/http_command.rb:194:in `process_response'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/lib/google/apis/core/http_command.rb:309:in `execute_once'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/lib/google/apis/core/http_command.rb:113:in `block (2 levels) in execute'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/retriable-3.1.2/lib/retriable.rb:61:in `block in retriable'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `times'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `retriable'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/lib/google/apis/core/http_command.rb:110:in `block in execute'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/retriable-3.1.2/lib/retriable.rb:61:in `block in retriable'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `times'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `retriable'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/lib/google/apis/core/http_command.rb:102:in `execute'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/lib/google/apis/core/base_service.rb:366:in `execute_or_queue_command'
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/google-api-client-0.44.0/generated/google/apis/admob_v1/service.rb:182:in `generate_network_report'
from sample.rb:35:in `<main>'
In this line:
from /Users/jonas/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/representable-3.0.4/lib/representable/json.rb:39:in `from_json'
# Parses the body as JSON and delegates to #from_hash.
def from_json(data, *args)
data = MultiJson.load(data)
from_hash(data, *args)
end
The code assumes data is a hash but it receives an array
[1] pry(#<Google::Apis::AdmobV1::GenerateNetworkReportResponse::Representation>)> data
=> [{"header"=>{"dateRange"=>{"startDate"=>{"year"=>2020, "month"=>1, "day"=>1}, "endDate"=>{"year"=>2020, "month"=>9, "day"=>1}}, "localizationSettings"=>{"currencyCode"=>"USD"}}}, {"row"=>{"metricValues"=>{"ESTIMATED_EARNINGS"=>{"microsValue"=>"1"}}}}, {"footer"=>{"matchingRowCount"=>"1"}}]
Unfortunately this isn't something we can fix in the client. The GenerateNetworkReport call is a streaming call, which is not described correctly in the API specification (discovery document), and so the client can't tell it's supposed to be an array.
Ok. Who is responsible for the API specification?
On Tue, 8 Sep 2020 at 22:21 Daniel Azuma [email protected] wrote:
Unfortunately this isn't something we can fix in the client. The GenerateNetworkReport call is a streaming call, which is not described correctly in the API specification (discovery document), and so the client can't tell it's supposed to be an array.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/googleapis/google-api-ruby-client/issues/902#issuecomment-689239894, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHE6KBHSKMK7SI5KYXRYMTSE3KCTANCNFSM4QTEXCWQ .
-- j^_^j
+1 Having the same issue.
👋 Greetings @jonasmora, for technical discussions with developers and members of the AdMob API team, visit the Google AdMob API Technical Forum.
I'm going to close this issue because the folks who own this repo have no actionable way to resolve it directly, but please let us know if there's anything we can do to help!
Reopening as it remains an issue, and we're tracking an active internal effort to address it internally.
As a workaround I did this
Google::Apis::AdmobV1::GenerateMediationReportResponse.class_eval do
attr_accessor :rows
end
Google::Apis::AdmobV1::GenerateMediationReportResponse::Representation.class_eval do
def from_json(data, *args)
data = MultiJson.load(data)
new_data = {}
data.each do |datum|
if datum.has_key? 'header'
new_data['header'] = datum['header']
elsif datum.has_key? 'row'
new_data['rows'] ||= []
new_data['rows'] << datum['row']
elsif datum.has_key? 'footer'
new_data['footer'] = datum['footer']
end
end
from_hash(new_data, *args)
end
collection :rows, as: 'rows', class: Google::Apis::AdmobV1::ReportRow, decorator: Google::Apis::AdmobV1::ReportRow::Representation
end