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

Unable to call to undefined method getRealContainingOneof #891 #978

Closed
mdworkin21 opened this issue Dec 27, 2023 · 13 comments
Closed

Unable to call to undefined method getRealContainingOneof #891 #978

mdworkin21 opened this issue Dec 27, 2023 · 13 comments
Labels
bug Something isn't working triage Need triage

Comments

@mdworkin21
Copy link

Your client library and Google Ads API versions:

  • Client library version: 21.0

  • Google Ads API version: V15

Your environment:

PHP Version 8.1.26

================= PHP EXTENSION INFORMATION The PHP Extension grpc is installed: 1.44.0 The PHP Extension protobuf is installed: 3.19.4

Description of the bug:

I'm running into what seems like the same issue as #891. I have followed the links and suggestions but have not been able to resolve the issue.(The issue was closed so I didn't know if I should post there, apologies for duplication if it was better to post in the other!)

The error: Call to undefined method Google\Protobuf\FieldDescriptor::getRealContainingOneof() Code: 0

I have checked vendor, and the file is there, along with the method.

I've been trying to track down how I can tell if I have 2 protobufs running (a PHP and a C, and one is interfering with the other) but have not been able to tell.

Steps to reproduce:

This has been happening when I've tried to update a campaign to a new bidding type. The error occurs when I call setUpdateFieldMasks. Below is some of the code used to update campaigns

 private function buildCampaign(array $data) : Campaign
    {
         //Validation check. If payload fails, throw exception
         if(!$this->hasRequredFields('id', $data, self::FIELD_LIST)){
            throw new Exception("Missing fields. Please make sure update contains id for campaign, and at least one field from the following list: ".json_encode(self::FIELD_LIST));
        }

        //Add resource name
        $data['resource_name'] = ResourceNames::forCampaign($this->account, $data['id']);
   
        if($data['status'] ?? false){
            $data['status'] = $this->getStatusValue($data['status']);
        }

        if($data['bidding_strategy'] ?? false){
      
            $data['target_cpa'] = new TargetCpa([
                "target_cpa_micros"=>(int) (1.01 * self::ONE_MILLION) //hard coding for testing
            ]);
            $data[strtolower($data['bidding_strategy'])] = $this->getBiddingStrategyValue($data);

        }



        //Unset extraneous fields
        $data = array_filter($data, function($field){
            return in_array($field, self::FIELD_LIST);
        }, ARRAY_FILTER_USE_KEY);

        
        //Return new Campaign
        return new Campaign($data);;
    }

//Helper function referenced above
private function getBiddingStrategyValue(array $data){

        switch(strtoupper($data['bidding_strategy'])){
            case "MAXIMIZE_CONVERSIONS":
                if(!isset($data['cpc_bid_ceiling_micros'])){
                    throw new Exception('Updating bidding strategy to TargetCpa requires target_cpa_micros');
                }

                return new MaximizeConversions(["cpc_bid_ceiling_micros"=>$data['cpc_bid_ceiling_micros'] * self::ONE_MILLION]);
            case "TARGET_CPA":
                if(!isset($data['target_cpa_micros'])){
                    throw new Exception('Updating bidding strategy to TargetCpa requires target_cpa_micros');
                }

                return new TargetCpa(["target_cpa_micros"=>$data['target_cpa_micros'] * self::ONE_MILLION]);
            

        }
    }

//Function that ends up calling fieldMask
/**
    * @param array $data array of arrays of data to turn into campaigns
    * @return array of CampaignOperations
    */
   public function buildCampaignOperations(array $data) : array
   {
       $operations = [];

       foreach($data as $datum){

            try {
                $campaign = $this->buildCampaign($datum);
                $operations[] = (new CampaignOperation())->setUpdate($campaign)->setUpdateMask(FieldMasks::allSetFieldsOf($campaign)); //THIS LINE CREATES ERROR, but when I remove that produces a different error,
            }

            catch(Exception $e){
                $this->addToResponse(['data'=>$datum, 'status_code'=>400, 'err'=>$e->getMessage()]);
            }
           
       }

       return $operations;
   }

Expected behavior:

  • Able to make the API call without the fatal error.

Request/Response Logs:

  • Request/response logs don't seem to come into play because I get a fatal error before it hits the logs.

Anything else we should know about your project / environment:
We're able to update campaigns when the updates are "simple", e.g., updating the status. When trying to update the bid strategy for a campaign, a few fields need to be updated at once, could this be part of the issue?

@mdworkin21 mdworkin21 added bug Something isn't working triage Need triage labels Dec 27, 2023
@fiboknacky
Copy link
Member

Sorry for late response. So, have you figured out what implementation (PHP or C) your system is using based on https://developers.google.com/google-ads/api/docs/client-libs/php/protobuf?

@mdworkin21
Copy link
Author

Hey, thanks for getting back to me. I think it's the PHP implementation. When I run protoc --version protoc is not installed. Are you aware of a better way to check?

@fiboknacky
Copy link
Member

@mdworkin21
Copy link
Author

Ah, sorry missed that. Yeah ran it and empty response, so it would seem php.

@fiboknacky
Copy link
Member

I have checked vendor, and the file is there, along with the method.

If PHP, would you be able to find a way to debug that in your IDE or print out something in the files along the call stack to confirm that they're called like you think?

@mdworkin21
Copy link
Author

Ok, so I traced through the code in the vendor files, and found where the getRealContainingOneof method is being called. It is being called in isSettingEmptyOneof method in Google\Ads\GoogleAds\Util\FieldMasks. I printed some things out to make sure that that line was indeed being hit, and it is.

One of the things I printed out was the $fieldDescriptor that supposedly has the getRealContainingOneof method on it. This gives me back a reference: Google\Protobuf\FieldDescriptor Object. When I go into that file in my vendor folder, I and add some print statements to other methods (which I called from isSettingEmptyOneof ), those prints do not appear. So it seems like for some reason, this file is not being called.

Within the Google\Protobuf directory, in addition to Google\Protobuf\FieldDescriptor , there is also a Google\Protobuf\Internal\FieldDescriptor file. This file does not have the getRealContainingOneof method. However, I'm not sure this is being called either, since I did the same sort of test (print lines, call from FieldMasks) and nothing printed.

So I have no idea what Google\Protobuf\FieldDescriptor is being called. I've been searching through vendor for conflicts, trying to see if this exists twice (for whatever reason), but as far as I can tell it doesn't.

@fiboknacky
Copy link
Member

Would it be possible for you to refresh your vendor/ like removing it and do composer install again?

@mdworkin21
Copy link
Author

I've tried that a number of times, and unfortunately no change.

@fiboknacky
Copy link
Member

So, your protobuf is a latest version now? I ask because the version you mentioned above is 3.19.4, which seems to be released around Jan 2022, whereas the support for getRealContainingOneOf was added around June 2022 (which was later released).

@mdworkin21
Copy link
Author

Ah I see, we have an older version of the extension installed (3.19.4). I kept trying to update the proto library that composer uses. So if we update the extension, presumably the error should go away?

@fiboknacky
Copy link
Member

Yep. Upgrading it to any versions after June 2022 should work.

@fiboknacky
Copy link
Member

Closing due to inactivity.

@mdworkin21
Copy link
Author

Hey, sorry for the long delay, I was on parental leave and am still getting caught up. For those facing similar problems, upgrading the extension does seem to have made the error disappear.

I'm getting other errors for what I'm trying to do, but not the one discussed above : )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage Need triage
Projects
None yet
Development

No branches or pull requests

2 participants