28

I have my app already submited, reviewed and online in Google Play & iTunes, but recently I added the firebase_messaging plugin for notification feature.

While joining the Firebase Cloud Messaging, Google forced me to download two files:

  • google-services.json - Saved in the folder of my flutter App: MyApp\android\app
  • GoogleService-Info.plist - I don't know where to save it, but tried on MyApp\ios\Runner and MyApp\ios\Runner.xcodeworkspace without success

And all the tutorials point to the use of Xcode to set the file GoogleService-Info.plist properly, but I do not own a Mac and I've been using with success the windows application AppUploader to submit my iOS apps.

Is there any way to not use the Xcode and be able to attach the GoogleService-Info.plist to my project?

Linesofcode
  • 5,327
  • 13
  • 62
  • 116

3 Answers3

18

If you want to avoid using Xcode, you have to manually edit this file : /ios/Runner.xcodeproj/project.pbxproj

You will need to reference GoogleService-Info.plist in order to make it included during the build process.

Here are the 4 differents sections where you need to add a line (see example line for GoogleService-Info.plist):

/* Begin PBXBuildFile section */
        1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
        3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
        3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
        3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
        74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
        9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
        9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
        97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
        DE4C455E21DE1E4300EA0709 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */; };
        97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
        97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */

Here :

/* Begin PBXFileReference section */
        1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
        1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
        3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
        3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
        74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
        74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
        7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
        9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
        9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
        9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
        97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
        97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
        97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
        97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
        97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
        DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };

/* End PBXFileReference section */

Here:

97C146F01CF9000F007C117D /* Runner */ = {
    isa = PBXGroup;
    children = (
        97C146FA1CF9000F007C117D /* Main.storyboard */,
        97C146FD1CF9000F007C117D /* Assets.xcassets */,
        97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
        97C147021CF9000F007C117D /* Info.plist */,
        DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */,
        97C146F11CF9000F007C117D /* Supporting Files */,
        1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
        1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
        74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
        74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
    );
    path = Runner;
    sourceTree = "<group>";
};

And here :

/* Begin PBXResourcesBuildPhase section */
        97C146EC1CF9000F007C117D /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
                3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
                97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
                97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
                DE4C455E21DE1E4300EA0709 /* GoogleService-Info.plist in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
/* End PBXResourcesBuildPhase section */

Tested successfully with codemagic, this modification made the provided GoogleService-Info.plist included in the App IPA

Fabien B
  • 181
  • 1
  • 3
  • 1
    can you please tell me how this numbers `97C147011CF9000F007C117D ` will get? – Priyanka Oct 11 '20 at 06:45
  • Open up XCode, copy/move the GoogleService-Info.plist into the Runner folder. When you do this, a dialog box will open up asking whether to add this new file to the project. Check on "copy the file if needed" and click on "Add". The entries will be automatically generated and added to ios/Runner.xcodeproj/project.pbxproj – Druhin Bala Dec 11 '20 at 15:05
  • So, if understood correctly, this is only a reference to the file and not its content, right? Meaning I can switch between staging and production files as long as I keep the "GoogleService-Info.plist" name and reference – Imed Boumalek Aug 08 '21 at 10:22
  • Saved my day! For other wondering: yeah, it actually works. Place your GoogleService-Info.plit in the ios/Runner folder and edit the /ios/Runner.xcodeproj/project.pbxproj as shown above – Bugzilla Jan 03 '22 at 22:29
  • Thanks Fabien, it works! I managed to create ios flutter app with firebase notifications using only Windows 10, no MacBook needed! :) – vladimirp Jan 18 '22 at 10:58
7

Somewhere along the line, AppUploader must be using XCode to build an iOS app from your code. While I don't know how they do that (their documentation is scarce on details), the best you can hope for is to put the google-services-info.plist in the right place before uploading the app.

In my projects I always put the google-services-info.plist in the myappname/ios/Runner directory that the Flutter tooling auto-generates. That's where the build then picks it up from.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 2
    I tried to put in `myappname/ios/Runner` first and then in`myappname\ios\Runner.xcodeworkspace` and created both IPA files using the `codemagic` platform. While testing both versions, the app crashes and I know that the reason is the file not being readed (?). – Linesofcode Jun 01 '19 at 14:18
  • 2
    @Linesofcode did you ever figure this out? I'm having the same problem with CodeMagic. – Nahele Allan-Moon Aug 31 '19 at 13:24
  • @NaheleAllan-Moon negative, I had to use XCode in a Virtual Machine. – Linesofcode Aug 31 '19 at 16:36
  • 1
    Thanks for your response. I've done the same thing and added the file to the Runner folder but I'm still getting error: Build input file cannot be found: '/Users/builder/GoogleService-Info.plist' Did you have this problem? – Nahele Allan-Moon Sep 01 '19 at 05:31
  • @NaheleAllan-Moon I did not, do you still have issues? – Linesofcode Sep 10 '19 at 15:21
5

after a while I bumped into it using the new XCode too I can guarantee you as already suggested that it works in this way.

Enter it under the

iOS -> Runner (here)

PS: From XCode I always took the reference of the file, it did not copy it to me. If anyone has succeeded even without this procedure above I would like to understand exactly how to do it from XCode.

AlexPad
  • 10,364
  • 3
  • 38
  • 48